c编程语言中的宏评估

可能重复:
“#define STR(a)#a”有什么作用?

#include  #define f(a,b) printf("yes") #define g(a) #a #define h(a) g(a) int main() { printf("%s\n",h(f(1,2))); printf("%s\n",g(f(1,2))); } 

有人可以解释为什么两个printf()语句的输出都不同。

由于预处理器执行操作的顺序,输出是不同的,这在C99标准的6.10.3节(及其后续节)中有所描述。 特别是6.10.3.1/1中的这句话:

替换列表中的参数,除非前面带有###预处理标记或后跟##预处理标记,否则在扩展其中包含的所有宏之后,相应的参数将替换该参数。

所以在第一行中,当扩展h的调用h ,参数f(1,2) 替换h的参数a 之前被展开。 只有当重新扫描所有内容的输出时,才能看到#的结果。

但在第二行, #立即被看到,上面引用的“除非前面……”条款触发了不同的行为。

另请参阅相关的C-FAQ条目 。

在预处理器完成宏扩展之后,编译器会看到:

  int main() { printf("%s\n","printf(\"yes\")"); printf("%s\n","f(1,2)"); } 

这是一种常见的技术,可以在“额外”间接中进行分层,以控制何时获得字符串化以及何时获得实际的宏评估。

基本上,宏观评估是从“外部”发生的,而不是相反的。 维基百科页面说“首先没有为宏替换解析参数”,我认为这是指同一件事。