“## b”在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年了,我很难过。 谷歌没有帮助,因为我不认为他们正在索引这些字符。

宏定义中的##符号表示串联。

所以

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

意思是

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

后处理到

 printf("hello world\n"); 

文档在这里 。

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

一个测试:

 /* test with * gcc -E test.c * having removed the #include lines for easier to read output */ #include  #include  #define concat(a,b) a ## b int main (int argc, char **argv) { concat (pri, ntf) ("Hello world\n"); exit (0); } 

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

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

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

那么,如果你打电话给CAT2

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

 CAT2(a_eval, b_eval) 

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