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

Moe*_*oeb 2 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]
 }
Run Code Online (Sandbox Code Playgroud)

输出:

12
f(1, 2)
Run Code Online (Sandbox Code Playgroud)

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

[我在这里理解了连接(a##b)和字符串转换(#a),但我不明白为什么输出在两种情况下都不同.]

Ste*_*sop 6

规范的相关部分是:

6.10.3.1

"在识别出类似函数宏的调用参数之后,会发生参数替换.替换列表中的参数,除非前面有#或##预处理标记或后跟##预处理标记(见下文) ),在其中包含的所有宏都被扩展后,被相应的参数替换."

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

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

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

printf("The value of the " g(NULL) " macro is " h(NULL));
Run Code Online (Sandbox Code Playgroud)