“## 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在评论中指出他的答案如下,没有它,它将连接指定的字面术语,而不是宏替换术语。 这里有一个有用的陷阱列表。
CAT2
和CAT3
是应该被调用的宏,另外两个是它们内部工作的一部分。
#define CAT2(a,b) CAT2EXP(a, b) #define CAT2EXP(a,b) a ## b
那么,如果你打电话给CAT2
?
好吧,首先替换CAT2
,它扩展了文字参数:
CAT2(a_eval, b_eval)
通过##
token连接运算符将两个参数连接成一个标记来替换它。