这个C代码如何工作?

什么是a##b#a

  #define f(a,b) a##b #define g(a) #a #define h(a) g(a) main() { printf("%s\n",h(f(1,2))); //how should I interpret this?? [line 1] printf("%s\n",g(f(1,2))); //and this? [line 2] } 

这个程序如何运作?


输出是

 12 f(1, 2) 

现在我明白a##b#a如何工作的。 但为什么两种情况(第1行和第2行)的结果不同?

##将两个令牌连接在一起。 它只能在预处理器中使用。

f(1,2)变为1 ## 2变为12

#运算符本身会对标记进行字符串化处理#a变为"a" 。 因此,当预处理器完成时, g(f(1,2))变为"f(1,2)"

h(f(1,2))实际上是#(1 ## 2) ,它变为#12 ,当预处理器在其上运行时变为"12"

对于这些问题(以及与预处理器有关的更多“真实世界”问题),我发现在预处理实际读取代码非常有帮助。

如何做到这一点因编译器而异,但是使用gcc,你会使用这个:

 $ gcc -E test.c (snip) main() { printf("%s\n","12"); printf("%s\n","f(1,2)"); } 

因此,您可以看到符号已连接在一起,并转换为字符串。

## b将粘贴代码togather。

所以f(1,2)将变为12

f(a,b)宏连接其参数,g(a)将其参数转换为字符串,h(a)是g(a)的辅助宏。 我想它会输出:

 12 f(1,2) 

原因是h(a)宏使其参数在传递给g(a)之前完全展开,而g(a)将从字面上理解其参数而不首先扩展它们。

a ## b是文字a和b的字符串连接,所以f(1,2)是“12”

#a是字符串文字a,所以g(3)是“3”

##是宏连接运算符。 所以例如f(foo,bar)相当于foobar

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

所以,##将两个部分直接组合在一起,无论它们是什么类型……给你一个例子.. printf("%d\n",f(1,2)); 你得到12,这意味着这里f(1,2)是12整数。

     int a2 = 100;
    的printf( “%d \ n” 个中,f(A,2));

这里f(a,2)是标签。 它指向代码上下文中的标签,如果没有int a2 = 100 ,则会出现编译错误。 并且#a将任何东西变成一个字符串…然后h(a) g(a)这很奇怪..看起来当你调用h(a)时,它转向g(a),并且通过a到g(a),首先,它解释了什么是a。 所以,在你可以g(a)之前,a被转换为f(a,b)= a ## b = 12