gpt4 book ai didi

c - 调用自身的宏打印自身?

转载 作者:太空狗 更新时间:2023-10-29 15:58:36 26 4
gpt4 key购买 nike

下面的程序看起来像一个调用自身的 C 宏。

#define q(k)int puts();int main(){puts(#k"\nq("#k")");}
q(#define q(k)int puts();int main(){puts(#k"\nq("#k")");})

It compiles and runs fine .它自己打印出来。

这段代码真的是 C 代码吗?也就是说,它是否依赖于标准 C 之外的任何东西才能正常工作?

@devnull 指出 this question有一个类似的程序:

#define q(k)main(){return!puts(#k"\nq("#k")");}
q(#define q(k)main(){return!puts(#k"\nq("#k")");})

这个程序是否依赖于标准 C 之外的任何东西才能正常工作?

最佳答案

第一个程序是用 C 语言实现 quine 的示例。在较高层次上,它定义了一个宏 q()。它创建了 main() 的定义打印出两行。第一行是参数本身,第二行是包裹在对 q() 的调用中的参数。本身。所以,下面的程序:

#define q(k)int puts();int main(){puts(#k"\nq("#k")");}
q(foo)

展开为:

int puts();int main(){puts("foo""\nq(""foo"")");}

编译运行后输出结果:

foo
q(foo)

用宏定义本身代替 foo结果是奎因。宏并不真正调用自身,它是在定义它的同一文本上调用的。在 C 中,宏不会递归展开(C.99 §6.10.3.4 ¶2)。

如问题中所述,该程序使用严格的 C.99 设置 ( -pedantic -std=c99 ) 在 GCC 下编译,没有任何投诉。该程序仅使用标准 C 功能,并符合 C.99 和 C.11。

  • 宏替换 (C.99 §6.10.3),带有参数替换 (C.99 §6.10.3.1) 和 # “字符串化”运算符(C.99 §6.10.3.2)。
  • 带有未指定参数列表的函数声明(C.99 §6.7.5.3 ¶14)。
  • 字符串文字连接(C.99 §5.1.1.2 ¶1)。
  • 默认 main()返回值(C.99 §5.1.2.2.3 ¶1)。

特别注意,该程序不依赖于字符的 ASCII 编码。

该程序将在 C.89-90 编译器上编译,但不从 main() 返回值的行为没有为 C.89-90 定义。通过添加 return 0; 可以对该程序进行简单修改,使其符合 C.89-90。在调用 puts() 后.

至于第二个节目,也是quine。但是,它不符合 C.89-90、C.99 或 C.11。这是因为它依赖于 puts()为逻辑非运算符返回一个正数,以便返回值为 0 .但是,C 只需要 puts()成功时返回一个非负值(C.99 §7.19.7.10 ¶3)。只有 C.89-90 允许隐式函数声明(C.89,§3.3.2.2)。通过删除 return! 可以修改程序以符合 C.89-90 , 然后添加 return 0;puts()之后打电话。

这些程序的结构在很大程度上受到书中 Gödel, Escher, Bach: An Eternal Golden Braid 中以“虚构”语言 BlooP 实现的 quine 程序的启发。 ,Douglas R. Hofstadter(因创造术语 quine 而受到赞誉)。

DEFINE PROCEDURE "ENIUQ" [TEMPLATE]: PRINT [TEMPLATE, LEFT-BRACKET,
QUOTE-MARK, TEMPLATE, QUOTE-MARK, RIGHT-BRACKET, PERIOD].
ENIUQ
['DEFINE PROCEDURE "ENIUQ" [TEMPLATE]: PRINT [TEMPLATE, LEFT-BRACKET,
QUOTE-MARK, TEMPLATE, QUOTE-MARK, RIGHT-BRACKET, PERIOD].
ENIUQ'].

顺便说一句,这是一个以相反顺序打印出其源代码的程序版本:

#define q(k)r(char*s){if(*s)r(s+1);putchar(*s);}main(){r(#k"\nq("#k")\n");}
q(#define q(k)r(char*s){if(*s)r(s+1);putchar(*s);}main(){r(#k"\nq("#k")\n");})

关于c - 调用自身的宏打印自身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17983034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com