C/C++预处理运算符
有三种运算符只能用在预处理指令中,它们是字符串化运算符#,粘贴运算符##和字符化运算符#@。
字符串化运算符#
在宏参数的前面放一个#会使编译器在展开宏时插入参数的名字而不是它的值。其主要效果是把参数的名字转换为字符串。下面的范例演示了字符串化运算符的语法:
#define STRINGLIZE(ivalue) printf(#ivalue " is: %d", ivalue)
...
...
...
int ivalue = 2;
STRINGLIZE(ivalue);
这个宏的输出如下:
ivalue is: 2
粘贴运算符##
当需要动态生成变量名或宏名的时候,粘贴运算符就很有用了。这个运算符删除它左右两边的空白字符,然后把左右两边剩 余的字符串连接在一起,构成一个新的字符串。特别地,它并不是简单地把左右两边的字符串常量做直接连接,而是把参数替换后再连接。也即它先进行宏替换,再 进行连接:
#define IVALUE_NAMES(icurrent_number) ivalue ## icurrent_number
...
...
...
int IVALUE_NAMES(1);
编译器把上面的代码看作下面的声明:
int ivalue1;
注意:预处理程序删去了空白字符,因为编译器不会把ivalue1看作是ivalue 1。这个运算符可以与其它预处理指令组合使用,构成复杂的定义。下面的范例使用了粘贴运算符来生成一个宏名,这会使预处理程序调用适当的宏:
#define MACRO1 printf("MACRO1 is invoked.")
#define MACRO2 printf("MACRO2 is invoked.")
#define MAKE_MACRO(n) MACRO ## n
...
...
...
MAKE_MACRO(2);
这个范例的输出将是:
MACRO2 is invoked.
字符化运算符#@
在宏定义中,字符化运算符放在一般的参数之前。这会使实际的参数被当作一个用单引号括起的字符。例如:
#define CHARIZEIT(cvalue) #@cvalue
...
...
...
clatter = CHARIZEIT(z);
编译器把上面的代码看作是:
clatter = 'z';
不过,在DevC++中,最后面的字符化运算符好像没有被支持,不知VC支持没有。