这个C代码如何工作?

时间:2009-11-06 09:00:49

标签: c c-preprocessor stringification

什么是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行)的结果不同?

7 个答案:

答案 0 :(得分:19)

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

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

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

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

答案 1 :(得分:5)

对于这些问题(以及与预处理器有关的更多“真实世界”问题),我发现实际读取代码非常有用,预处理之后。< / p>

如何做到这一点因编译器而异,但使用gcc,您可以使用:

$ gcc -E test.c

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

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

答案 2 :(得分:4)

## b将粘贴代码togather。

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

答案 3 :(得分:3)

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

12
f(1,2)

原因是h(a)宏在将参数传递给g(a)之前使其参数完全展开,而g(a)将逐字地获取其参数而不首先扩展它们。

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

##是宏连接运算符。例如,f(foo,bar)等同于foobar

答案 6 :(得分:0)

  #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