6

什么是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但是为什么这两种情况(第 1 行和第 2 行)的结果不同呢?#a

4

7 回答 7

19

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

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

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

h(f(1,2))是有效的#(1 ## 2),当预处理器运行在它上面时,它就#12变成了。"12"

于 2009-11-06T09:05:55.373 回答
5

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

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

$ gcc -E test.c

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

因此,您可以看到符号已被连接起来,并变成了一个字符串。

于 2009-11-06T09:07:30.300 回答
4

a##b 将代码粘贴在一起。

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

于 2009-11-06T09:04:40.747 回答
3

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

12
f(1,2)

原因是 h(a) 宏导致它的参数在传递给 g(a) 之前被完全扩展,而 g(a) 将按字面意思接受它的参数而不先扩展它们。

于 2009-11-06T09:06:38.460 回答
0

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

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

于 2009-11-06T09:06:14.310 回答
0

## 是宏连接运算符。因此,例如f(foo,bar)将等效于foobar.

于 2009-11-06T09:07:14.907 回答
0
  #define f(a,b) a##b
  #定义 g(a) #a
  #define h(a) g(a)

所以,## 将 2 个部分直接组合在一起,无论它们是什么类型......举个例子...... 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把a是什么,变成一个字符串……然后h(a) g(a) 就很奇怪了……看起来,当你调用h(a)时,它变成了g(a),然后将a传入g(a),首先,它解释 a 是什么。所以,在你可以 g(a) 之前,a 被转换为 f(a,b) = a##b = 12

于 2009-11-06T09:39:17.503 回答