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

时间:2010-08-20 19:09:08

标签: c++ c c-preprocessor

我正在阅读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=markup。您可以使用CTRL + F找到它。

4 个答案:

答案 0 :(得分:20)

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

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

答案 1 :(得分:5)

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

说你有:

STR(MyClass);

它将被预处理为:

"MyClass";

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

答案 2 :(得分:4)

#a被称为stringizer operator。它采用形式参数,在本例中为a,并通过用双引号括起来将其转换为字符串。

所以如果你有:

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

输出结果为:

"my quoted string"

答案 3 :(得分:4)

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

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

#define a value_a

printf("%s", XSTR(a));

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