“#define STR(a)#a”有什么作用?

我正在阅读phoneME的源代码。 这是一个FOSS JavaME实现。 它是用C ++编写的,我偶然发现了这个:

// Makes a string of the argument (which is not macro-expanded) #define STR(a) #a 

我知道C和C ++,但我从来没有读过这样的东西。 #a中的#是做什么的?

此外,在同一个文件中,有:

 // Makes a string of the macro expansion of a #define XSTR(a) STR(a) 

我的意思是,定义一个新宏有什么用,如果它只是调用一个现有的宏?

源代码位于https://phoneme.dev.java.net/source/browse/phoneme/releases/phoneme_feature-mr2-rel-b23/cldc/src/vm/share/utilities/GlobalDefinitions.hpp?rev=5525&view =标记 。 你可以用CTRL + F找到它。

在第一个定义中, #a表示将宏参数打印为字符串。 这将转变为例如STR(foo)"foo" ,但它不会对其参数进行宏扩展。

第二个定义不会向第一个定义添加任何内容,但通过将其参数传递给另一个宏,它会强制其参数的完全宏扩展。 因此, XSTR(expr)创建一个expr字符串,所有宏都完全展开。

#是字符串化运算符。 预处理器从参数中生成一个字符串。

说你有:

 STR(MyClass); 

它将被预处理为:

 "MyClass"; 

间接级别(使用XSTR())与宏扩展规则有关。

首先,您应该知道这对宏实际上相当普遍。 第一个完全正如评论所说的那样 – 它通过将参数括在双引号中将参数转换为字符串。

第二个用于引起参数的宏扩展。 您通常将它们一起使用,如下所示:

 #define a value_a printf("%s", XSTR(a)); 

宏扩展将扩展为string_a ,stringify将其转换为字符串,因此输出将为value_a

#a称为字符串化运算符 。 它采用forms参数,在本例中为a ,并通过用双引号括起来将其转换为字符串。

所以如果你有:

 string s = STR("my quoted string"); cout << s; 

输出将是:

 "my quoted string"