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)");
}