c语言中的宏计算

c语言中的宏计算,c,macros,C,Macros,可能重复: #包括 #定义f(a,b)printf(“是”) #定义g(a)#a #定义h(a)g(a) int main() { printf(“%s\n”,h(f(1,2)); printf(“%s\n”,g(f(1,2)); } 有人能解释为什么两个printf()语句的输出不同。预处理器完成宏扩展后,编译器会看到: int main() { printf("%s\n","printf(\"yes\")"); printf("%s\n","f(1

可能重复:

#包括
#定义f(a,b)printf(“是”)
#定义g(a)#a
#定义h(a)g(a)
int main()
{
printf(“%s\n”,h(f(1,2));
printf(“%s\n”,g(f(1,2));
}

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

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

  int main()
  {
        printf("%s\n","printf(\"yes\")");
        printf("%s\n","f(1,2)");
  }
这是一种常见的技术,它以“额外”间接方式分层,以控制何时进行字符串化以及何时进行实际的宏计算


基本上,宏观评估是从“外部到内部”进行的,而不是相反。上面说“参数不首先解析用于宏替换”,我认为这是指同一件事。

输出不同,因为预处理器执行操作的顺序不同,这在C99标准的第6.10.3节(以及后面的部分)中有描述。特别是6.10.3.1/1中的这句话:

替换列表中的参数,除非前面有
预处理标记,或后面有
预处理标记,否则在展开其中包含的所有宏后,将被相应的参数替换

因此在第一行中,当展开
h
的调用时,参数
f(1,2)
在替换
h
的参数
a
之前展开。
#
只有在重新扫描所有结果的输出时才能看到对
g
的结果调用时才起作用

但是在第二行,立即可以看到
#
,并且上面引用的“除非前面有…”子句触发了不同的行为

另见

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