string化 – 它是如何工作的?
我知道:
#define foo 4 #define str(s) #s
用str(foo)
写出来: "foo"
,因为stringify先执行文本扩展,但是这个:
#define xstr(s) str(s) #define str(s) #s #define foo 4
用xstr(foo)
写出: "4"
。
为什么? 这个过程涉及哪些步骤?
macros观扩展的相关步骤是(根据C 2011 [n1570] 6.10.3.1和C ++ 1998 16.3.1):
- 处理以
#
或##
令牌。 - 将macrosreplace应用于每个参数。
- 将每个参数replace为上述macrosreplace的相应结果。
- 重新扫描更多的macros。
因此,用xstr(foo)
,我们有:
- replace文本
str(s)
不包含#
或##
,所以没有任何反应。 -
foo
的参数被replace为4
,所以就好像xstr(4)
已被使用。 - 在replace文本
str(s)
,参数s
被replace为4
,产生str(4)
。 -
str(4)
被重新扫描。 (由此产生的步骤产生”4”
。
请注意, str(foo)
的问题在于,第2步将用4
replacefoo
,在第1步之后,将参数更改为string。 在第一步, foo
还是foo
; 它并没有被4
取代,所以结果是”foo”
。
这就是为什么使用助手macros的原因。 它允许我们执行第2步,然后使用另一个macros执行第1步。
第一种情况
- 评估
str(foo)
:用#foo
replacestr(foo)
,即"foo"
第二种情况
- 评估
xstr(foo)
:用str(<foo-value>)
replacexstr(foo)
str(<foo-value>)
,即str(4)
- 评估
str(4)
:用#4
replacestr(4)
,即"4"
通常,
预处理器评估扩展macrosvariables的macros函数, 直到没有任何评估 :
如果你定义
#define xstr(s) str(s) + 1 #define str(s) s + 1
在下面的代码中
#define foo 4 int main() { std::cout << str(foo) << '\n' << xstr(foo) << '\n' ; }
它会评估像
第一个string
- 用
<foo-value> + 1
replacestr(foo)
,即4 + 1
- 没有什么可以替代的。 精加工。
结果是4 + 1
第二个string
- 用
str(<foo-value>) + 1
replacexstr(foo)
,即str(4) + 1
- 用
<4-value> + 1
代替str(4)
,即4 + 1
- 没有什么可以替代的。
结果是4 + 1 + 1