合并操作符,将出现在其左右的字符序列合并成一个新的标识符,产生的标识符必须预先有定义,否则编译器会报“标识符未定义”的编译错误。
标识符:
编程语言中就是对象,指针,引用的命名。
例如在程序中声明:
int iValue = 100;
这个int对象的值为100,其标识符为iValue,函数的标识符更加复杂,这里只谈变量标识符。
##用法:
在带参数的宏定义中,宏体内使用##将入参的标识符进行拼接。
例如:
#define CLASSNAME(name) classtype##name
#define CLASSNAME2(name) class1##class1
宏引用函数:
void func()
{
//必须先定义给宏的入值
int INT = 10;
char CHAR = 's';
//然后定义通过宏可能得到的标识符以及值
int classtypeINT = 1000;
char classtypeCHAR = 'e';
int INTINT = 12;
char CHARCHAR = 'q';
//检测宏引用分别得到了什么值
cout << CLASSNAME(INT) << endl;//classtypeINT
cout << CLASSNAME(CHAR) << endl;//classtypeCHAR
cout << CLASSNAME2(INT) << endl;//INTINT
cout << CLASSNAME2(CHAR) << endl;//CHARCHAR
}
运行结果:
这个例子中有大量细节需要注意:
1、区别于宏定义单纯的字符替换,当宏定义的宏体中出现了##操作符,就可以确定这个宏定义的作用是组合一个标识符,而不再只是替换。
2、该宏定义本质上不会修改代码,但已经起到了函数的功能(将入值的标识符转换成其他标识符)。
3、在宏体中,##的出现也意味着“拼接功能”,直接出现的字符串不需要放在引号中,被##操作符获取到的入值得标识符字符串表示为##x,按照需要的顺序进行排列,让字符串和##x直接拼接,组合成想要的标识符。
4、当出现了##操作符后,该操作符前面的入值即便没有##也会自动变成组成标识符的字符串。
5、这里##x中##操作符前面的空格是否存在,存在多少均不会影响结果形成的标识符。
6、这里##x后面无法通过跟空格和字符串的形式进行标识符向后拼接,但可以后接其它入值的##,也就是##这个这个操作符想要加直接字符串,只能从前面加,但可以通过简单的算法达成后加的效果。