什么是' a ## b'在C?

时间:2014-10-26 18:05:06

标签: c

来自usbtiny / defs.h(ATTiny控制器的AVR libc USB代码):

#define CAT2(a,b)               CAT2EXP(a, b)
#define CAT2EXP(a,b)            a ## b
#define CAT3(a,b,c)             CAT3EXP(a, b, c)
#define CAT3EXP(a,b,c)          a ## b ## c

什么是##运算符?我已经这样做了30年了,我很难过。谷歌并没有帮助,因为我不认为他们会将这些字符编入索引。

2 个答案:

答案 0 :(得分:9)

宏定义中的##符号表示连接。

所以

#define concat(a,b) a ## b

意味着

concat (pri, ntf) ("hello world\n");

后处理

printf("hello world\n");

文档here

同样有用的是stringify运算符(#),不应该与此混淆。

测试:

/* test with
 *    gcc -E test.c
 * having removed the #include lines for easier to read output
 */

#include <stdio.h>
#include <stdlib.h>

#define concat(a,b) a ## b

int
main (int argc, char **argv)
{
  concat (pri, ntf) ("Hello world\n");
  exit (0);
}

为什么额外的间接水平?正如Deduplicator在评论中指出他的答案如下,没有它,它将连接指定的字面术语,而不是宏替换术语。这些陷阱的有用列表是here

答案 1 :(得分:2)

CAT2CAT3是应该调用的宏,另外两个是内部工作的一部分。

#define CAT2(a,b)               CAT2EXP(a, b)
#define CAT2EXP(a,b)            a ## b

那么,如果你拨打CAT2会怎么样?

好吧,首先替换CAT2,它会扩展文字参数:

CAT2(a_eval, b_eval)

通过##标记连接运算符将两个参数连接成一个标记来替换它。