在函数式宏定义中,#
运算符用于创建字符串,#
运算符后面应该跟一个形参(中间可以有空格或Tab),例如:
#define STR(s) # s STR(hello world)
用cpp
命令预处理之后是"hello world"
,自动用"
号把实参括起来成为一个字符串,并且实参中的连续多个空白字符被替换成一个空格。
再比如:
#define STR(s) #s fputs(STR(strncmp("ab/"c/0d", "abc", '/4"') == 0) STR(: @/n), s);
预处理之后是fputs("strncmp(/"ab///"c//0d/", /"abc/", '//4/"') == 0" ": @/n", s);
,注意如果实参中包含字符常量或字符串,则宏展开之后字符串的界定符"
要替换成/"
,字符常量或字符串中的/
和"
字符要替换成//
和/"
。
在宏定义中可以用##
运算符把前后两个预处理Token连接成一个预处理Token,和#
运算符不同,##
运算符不仅限于函数式宏定义,变量式宏定义也可以用。例如:
#define CONCAT(a, b) a##b CONCAT(con, cat)
预处理之后是concat
。再比如,要定义一个宏展开成两个#
号,可以这样定义:
#define HASH_HASH # ## #
中间的##
是运算符,宏展开时前后两个