#define宏
1. 用宏定义表达式完成加法运算函数
#define ADD(x,y) ((x)+(y))
宏会替换到调用宏函数的地方,这是毋庸置疑的。
- 为什么x+y的整体要加上() ?
- 那么为什么参数x,y要加上() ?
我们来结合代码看一下吧。
#define ADD(x,y) x+y
int main()
{
int x1 = 3;
int x2 = 5;
printf("%d\n", ADD(x1,x2)*ADD(x1,x2) ); //被替换为 3+5*3+5 = 23
}
结果:
分析:
我们预期的结果应该是 8 * 8 = 64, 为什么是23呢? 因为它被替换为 3+5 * 3+5 = 23 。所以我们要加上(), (3+5)*(3+5)才等于64,我们期待的答案。所以x+y的整体要加上()。
- 那么为什么参数的x,y都要加上() ?
因为运算符的优先级不一样,参数x,y可能是表达式
#define ADD(x,y) (x + y)
int main ()
{
int x1 = 1;
int x2 = 2;
printf("%d\n" , ADD(x1|x2,x1|x2)); //被替换为 1|2 + 1|2 = 3 ; '+'的优先级比 '|'高
}
结果:
分析: 我们预期的结果是3+3 = 6。 但是结果为3。 因为’+'的优先级比 '|'高 。 没有先运算x1|x2 , 所以加上(), (x1|x2)+(x1|x2)。
2. 用宏定义表达式完成两个数的交换
#define SWAP(Type,name,x,y)\ //Type 交换的变量x,y的类型
Type c##name = x;\
x = y;\
y = c##name
int main()
{
int a = 0;
int b = 3;
printf("a = %d, b = %d\n", a, b);
SWAP(int, 1, a, b);
printf("a = %d, b = %d\n", a, b);
system("pause");
}
结果:
分析:
我们先来讲一下’’ 和 ‘##’ 符号的作用
’’ : 续航符,宏定义一行没有结束的时候,换行写的时候,在前面一行的末尾加上换行符。
注:续航符的后面不能加空格或者Tab。
’##’: 把两边的符号合成一个符号。 比如在这里就是将变量c和name合成一个变量
#define SWAP(Type,name,x,y)
Type c##name = x;
x = y;
y = c##name
SWAP(int, 1, a, b) 就是
int c1 = a;
a = b;
b = c1;
那么为什么要加上name这个参数?
因为多次调用这个宏的时候,会多次宏替换,会多次定义出变量c,重定义变量,会报错。所以第一调用的时候SWAP(类型,1,x,y), 第二次调用的时候SWAP(类型,2,x, y), 。。。
就会定义出不同的变量 c1, c2, c3 …cn 。
3. 下面运算后x,y,z的值是多少?
#define MAX(a,b) ((a) >(b) ? (a):(b))
int main()
{
int x = 5;
int y = 8;
z = MAX(x++,y++);
printf("x = %d , y = %d , z =%d\n", x,y,z); // 6, 10 , 9
}
分析:
将MAX的函数替换到main函数中的位置。 z = ((x++) >(y++) ? (x++):(y++));
先x++,此时x=6, 但是返回的是5;
y++, 此时y=9, 但是返回的是8;
z = 5 > 8 ? (x++) ? (y++); // z = 5 > 8 ? (6++) ? (9++);
5 > 8 不成立, 所以y++, 此时 y= 10; 返回的是9。
所以z = 9,y = 10, x = 6