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):

  1. 处理以###令牌。
  2. 将macrosreplace应用于每个参数。
  3. 将每个参数replace为上述macrosreplace的相应结果。
  4. 重新扫描更多的macros。

因此,用xstr(foo) ,我们有:

  1. replace文本str(s)不包含### ,所以没有任何反应。
  2. foo的参数被replace为4 ,所以就好像xstr(4)已被使用。
  3. 在replace文本str(s) ,参数s被replace为4 ,产生str(4)
  4. str(4)被重新扫描。 (由此产生的步骤产生”4”

请注意, str(foo)的问题在于,第2步将用4replacefoo ,在第1步之后,将参数更改为string。 在第一步, foo还是foo ; 它并没有被4取代,所以结果是”foo”

这就是为什么使用助手macros的原因。 它允许我们执行第2步,然后使用另一个macros执行第1步。

第一种情况

  1. 评估str(foo) :用#fooreplacestr(foo) ,即"foo"

第二种情况

  1. 评估xstr(foo) :用str(<foo-value>)replacexstr(foo) str(<foo-value>) ,即str(4)
  2. 评估str(4) :用#4replacestr(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

  1. <foo-value> + 1replacestr(foo) ,即4 + 1
  2. 没有什么可以替代的。 精加工。

结果是4 + 1

第二个string

  1. str(<foo-value>) + 1replacexstr(foo) ,即str(4) + 1
  2. <4-value> + 1代替str(4) ,即4 + 1
  3. 没有什么可以替代的。

结果是4 + 1 + 1