#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
是否有可能连接STR3 ==“s1”?您可以通过将args传递给另一个宏函数来完成此操作。但是有直接的方法吗?
如果它们都是字符串,你可以这样做:
#define STR3 STR1 STR2
预处理器自动连接相邻的字符串。
编辑:
如下所述,它不是预处理器,而是执行串联的编译器。
你不需要那种字符串文字的解决方案,因为它们在语言级别连接,并且它无论如何都不会起作用,因为“s”“1”不是有效的预处理器标记。但是,对于一般的令牌粘贴,请尝试以下方法:
/*
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define PPCAT_NX(A, B) A ## B
/*
* Concatenate preprocessor tokens A and B after macro-expanding them.
*/
#define PPCAT(A, B) PPCAT_NX(A, B)
然后,例如,PPCAT(s, 1)
产生标识符s1
。
继续主题是这些宏:
/*
* Turn A into a string literal without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define STRINGIZE_NX(A) #A
/*
* Turn A into a string literal after macro-expanding it.
*/
#define STRINGIZE(A) STRINGIZE_NX(A)
然后,
#define T1 s
#define T2 1
STRINGIZE(PPCAT(T1, T2)) // produces "s1"
提示:上面的STRINGIZE
宏很酷,但如果你犯了一个错误并且它的参数不是一个宏 - 你的名字中有一个拼写错误,或者忘了#include
头文件 - 那么编译器会愉快地把声称的宏名称进入字符串没有错误。
如果你打算STRINGIZE
的参数总是一个具有正常C值的宏,那么
#define STRINGIZE(A) ((A),STRINGIZE_NX(A))
将它扩展一次并检查它的有效性,丢弃它,然后再将它再次扩展为一个字符串。
我花了一段时间才弄清楚为什么STRINGIZE(ENOENT)
最终成为"ENOENT"
而不是"2"
...我没有包括errno.h
。