为什么以下两个语句的输出不同?

时间:2009-11-06 12:38:31

标签: c function

代码:

 #define f(a,b) a##b
 #define g(a)   #a
 #define h(a) g(a)

 main()
 {
      printf("%s\n",h(f(1,2)));  //[case 1]
      printf("%s\n",g(f(1,2)));  //[case 2]
 }

输出:

12
f(1, 2)

为什么两种情况下的输出都不相同?

[我理解连接(a##b)和字符串转换(#ahere,但我不明白为什么输出在两种情况下都不同。] < / em>的

4 个答案:

答案 0 :(得分:6)

规范的相关部分是:

6.10.3.1

“在确定了调用类函数宏的参数之后, 参数替换发生。替换列表中的参数,除非在前面 通过#或##预处理令牌或后跟##预处理令牌(见下文),是 在其中包含的所有宏之后用相应的参数替换 扩大“。

换句话说,当替换宏参数时,首先在参数上有一轮宏扩展,除非参数出现#或##。

所以g(blah)只是将blah字符串化。 h(blah)首先进行宏扩展blah,然后将其字符串化。

当您想要对宏名称进行字符串化时,差异尤为重要:

printf("The value of the " g(NULL) " macro is " h(NULL));

答案 1 :(得分:1)

这可能是评估的顺序。在第一种情况下,h和f在第一次传递到g和12时得到评估。宏评估的第二次传递然后将其转换为12.在第二种情况下,g直接将f(1,2)计算为字符串。

答案 2 :(得分:1)

当扩展函数样式宏时,替换列表中不以#开头或紧邻##的任何参数实例在宏扩展后被相应的参数替换。对于#之后或与##相邻的参数,不会发生宏扩展。如果扩展中还有任何宏,则在替换时会递归宏扩展,直到没有剩余的宏为止。 (任何宏的扩展在任何嵌套级别的扩展期间都不会自行扩展,因此无法获得任何无限递归。)

在您的示例中,g(f(1,2))变为# f(1,2)(不扩展宏参数),即“f(1,2)”,字符串文字。

h(f(1,2))变为g( 12 )因为f(1,2)经历了宏扩展,此扩展中有剩余的宏,因此会再次展开,g( 12 )变为“12”。 / p>

答案 3 :(得分:0)

C宏不是函数。这是简单的文本替换。只需将g(a)中的 a 替换为“f(1,2)”,这就是你的答案。