算符优先级问题:

#define COUNT(M) M*Mint x=5;print(COUNT(x+1));print(COUNT(++X));//结果输出:11 和42 而不是函数的输出36

注意:

预编译器只是进行简单的文本替换,COUNT(x+1)被替换成COUNT(x+1 x+1),5+15+1=11,而不是36

CUNT(++x)被替换成++x*++x即为6 *7=42,而不是想要的6*6=36,连续前置自加加两次

解决办法:

用括号将整个替换文本及每个参数用括号括起来print(COUNT((x+1));

即便是加上括号也不能解决第二种情况,所以解决办法是尽量不使用++,-等符号;分号吞噬问题:

#define foo(x) bar(x); baz(x)

假设这样调用:

if (!feral) foo(wolf);

将被宏扩展为:

if (!feral) bar(wolf);baz(wolf);

==baz(wolf);==,不在判断条件中,显而易见,这是错误。如果用大括号将其包起来依然会有问题,例如

#define foo(x) { bar(x); baz(x); }if (!feral) foo(wolf);else bin(wolf);

判断语言被扩展成:

if (!feral) { bar(wolf); baz(wolf);}》》++;++《《else bin(wolf);

==else==将不会被执行

解决方法:通过==do{…}while(0)

#define foo(x) do{ bar(x); baz(x); }while(0)if (!feral) foo(wolf);else bin(wolf);

被扩展成:

#define foo(x) do{ bar(x); baz(x); }while(0)if (!feral) do{ bar(x); baz(x); }while(0);else bin(wolf);

注意:使用do{…}while(0)构造后的宏定义不会受到大括号、分号等的影响,总是会按你期望的方式调用运行。

#运算符

#的作用就是将#后边的宏参数进行字符串的操作,也就是将#后边的参数两边加上一对双引号使其成为字符串。例如a是一个宏的形参,则替换文本中的#a被系统转化为“a”,这个转换过程即为字符串化。