最近工作中的runfunction和面试中总是遇到函数宏定义,所以看了看,做了总结.
在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”. 如果字符串是表达式就称为函数宏.
函数宏的缺点:
1. 函数宏没有参数检查,所以运用的时候要小心.
2.代码中出现的每次宏调用编译生成的指令都相当于一个函数体,而不是简单的几条传参指令和call指令,所以,使用函数式宏定义编译生成的目标文件会比较大
3.函数式宏定义要注意格式,尤其是括号.
4. 若函数参数为表达式,则普通函数的调用与函数式宏定义的替换过程是不一样的
普通函数是计算出来表达式的值,然后传递,而函数宏 则是简单的宏替换. 比如 #define MAX(a,b) ((a)>(b)?(a),(b))
void MAX(int a,int b),如果传递的是 MAX(++a,++b),这样的话普通函数只是自增一次就行,函数宏就不止一次了.
5. 一般情况下函数宏容易生产效率 低下的代码,特别是出现递归调用的时候.
int a[]={9,3,5,2,1,0,8,7,6,4};
int max(n)
{
return n==0?a[0]:MAX(a[n],max(n-1));
}
int main()
{
max(9);
return 0;
}
最后总结,为什么那么多缺点还用那么多呢,就是因为函数宏省略了一系列的分配栈和释放栈,传递参数,传递返回值等动作,所以用处多,大概知道的就那么多了.
最后还有一点,#define 定义函数宏的时候,如果多行,需要在每一行的末尾加上 "\",起到换行的作用.