我正在阅读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找到它。
答案 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
。