1.带副作用的宏参数
当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能
出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。
x+1;//不带副作用
x++;//带有副作用
当我们运行下面的代码
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
...
x = 5;
y = 8;
z = MAX(x++, y++);
printf("x=%d y=%d z=%d\n", x, y, z);
//当编译器进行完预处理后,将会替换成下列代码
z = ( (x++) > (y++) ? (x++) : (y++));
//因此结果是
x=6 y=10 z=9
2.宏定义中的#和##
首先我们看看这样的代码:
char* p = "hello ""world\n";
printf("hello"" world\n");//1
printf("%s", p);//2
这里1和2能不能正常打印hello world,答案是可以的,因为字符串具有自动连接的特点。
因此我们可以这样使用宏定义
#define PRINT(FORMAT, VALUE)\
printf("the value is "FORMAT"\n", VALUE);
...
PRINT("%d", 10);
#
在这里c语言还提供了一个操作就是使用 # ,把一个宏参数变成对应的字符串
例如
int i = 10;
#define PRINT(FORMAT, VALUE)\
printf("the value of " #VALUE "is "FORMAT "\n", VALUE);
...
PRINT("%d", i+3);//产生了什么效果?
代码中的 #VALUE 会预处理器处理为: "VALUE" .
最终的输出的结果应该是:
the value of i+3 is 13
##
##可以把位于它两边的符号合成一个符号。 它允许宏定义从分离的文本片段创建标识符。
#define ADD_TO_SUM(num, value) \
sum##num += value;
...
ADD_TO_SUM(5, 10);//作用是:给sum5增加10.
注: 这样的连接必须产生一个合法的标识符。否则其结果就是未定义的。