目录
一、带有副作用的宏参数
#include <stdio.h>
#define MAX(X, Y) (X)>(Y)?(X):(Y)
int main()
{
int a = 10;
int b = 11;
int max = MAX(a++, b++);
printf("%d\n", max);
printf("%d\n", b);
printf("%d\n", a);
return 0;
}
此时的结果是12 13 11。宏的计算是参数直接替换,上面的代码替换过去就是
int max = ((a++) > (b++)) ? (a++) : (b++)。a和b先比较,发现为假,所以要执行最后的b++。比较完后ab先++,各自变成11,12,然后执行b++,b就会变成13。这就是一种副作用
二、宏和函数对比
#define MAX(X, Y) ((X)>(Y)?(X):(Y))
int Max(int x, int y)
{
return (x > y ? x : y);
}
int main()
{
int a = 10;
int b = 11;
int max = Max(a, b);
printf("max = %d\n", max);
max = MAX(a, b);
printf("max = %d\n", max);
return 0;
}
对于整形,两者都没问题,如果是浮点型,那么函数就得换成浮点型 ,而宏是类型无关的。函数在调用时,要执行函数调用和返回的汇编代码比宏多,宏在预处理阶段就完成替换,没有调用和返回的过程,效率更高。
宏也有缺点
每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。(如果宏定义的代码数很多,那么多次调用将会占据很多空间)
宏无法调试(开始调试时调试的是可执行程序,而宏在预处理阶段就完成替换,所以没法调试)
宏由于类型无关,就会不严谨
宏可能会带来运算符优先级的问题,导致程序容易出现错。
宏的参数也可以是类型
#define SIZEOF(type) sizeof(type)
int main()
{
int ret = SIZEOF(int);
//int ret = sizeof(int);
printf("%d\n", ret);
return 0;
}
这样就是在计算int类型的字节大小。在动态分配时,宏也可以有作用
#define MALLOC(num, type) (type*)malloc(num*sizeof(type))
int main()
{
int* p = MALLOC(10, int);
//相当于int* p = (int*)malloc(10*sizeof(int))
return 0;
}
三、#undef
用于移除一个宏定义
#define MAX 100
int main()
{
printf("MAX = %d\n", MAX);
#undef MAX
printf("MAX = %d\n", MAX);
return 0;
}
再次打印就出错,因为此时MAX已经没有了。
结束。