正如维基百科中提到的C-preprocessor:
## 运算符(称为“令牌粘贴运算符”)连接
两个令牌合为一个令牌。
# 运算符(称为“字符串化运算符”)将一个
标记为字符串,适当地转义任何引号或反斜杠。
如果你想字符串化宏参数的扩展,你有
使用两个级别的宏:
您不能将宏参数与附加文本和字符串化结合使用
这一切都在一起。但是,您可以编写一系列相邻的字符串
常量和字符串化参数:然后 C 编译器将结合
将所有相邻的字符串常量合并为一个长字符串。
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo) // outputs "foo"
xstr (foo) // outputs "4"
另外,from C-FAQ Question 11.17:
原来 # 的定义说它应该
立即字符串化宏参数,而不进一步扩展它
(如果参数恰好是另一个宏的名称)。
所以,类似地,沿着这些路线前进:
you're doing C(A(1,2)),
which would roll to C(12), // since no #, so inner argument is expanded
and then to B(12)
// [since you've done two levels of macros in the code:
// 1. from C() to B(), and then, 2. B() to #a]
= 12 .
然而,在第一种情况下,根据 B(a) 的定义,显然只完成了 1 级字符串化(因为它立即被字符串化,因为 #)
macro-replacement of B(A(1,2))
= stringification of A(1,2)
= A(1,2).