函数和宏的优点
执行速度
#define ADD(a,b) ((a)+(b))
函数的调用和返回是要消耗性能的,对于进行简单运算的时候,实际计算的性能损耗可能还没有函数调用,返回需要的耗费的性能要高。 宏是替换,不是传值。不需要额外损耗性能。从这个角度上看使用宏比函数效率要高。
代码长度
当多次使用宏时,宏代码都会插入程序中,除了长度很短的宏。都会明显增加代码长度。
而函数只需要出现在一个地方定义一次。每次使用调用即可。
参数
宏的参数求值在整个上下文环境。
#define SQUARE(X) X*X
int main()
{
int res = SQUARE(5 + 1);
printf("%d", res);
return 0;
}
res的值并不像我们预期的一样是36。而是11。
等价于SQUARE(5 + 1) == 5 + 1 * 5 + 1
所以我们防止运算符的优先级问题适当的给语句加上括号,保证运算顺序的正确。
其外,宏的参数是可能有副作用的。
#define MAX(A,B) (A)>(B)?(A):(B)
int main()
{
int a = 10;
int b = 11;
int max = MAX(a++, b++);//a=11 b=13 max = 12
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", max);
return 0;
}
计算的结果于预期不符。因为像这种带有++ – 的参数是有副作用的。
宏会因为这种带有副作用的参数可能导致程序出现不可预料的后果。
函数是计算后得出结果后传参。表达式的计算结果更容易预测。
参数类型
宏是与类型无关的。只要对参数的操作符合语法,他可以适用于任何参数类型。
而函数与类型有关。只要传递的参数和函数定义的参数不符。就需要不同的函数。
调试
宏是在预编译阶段就把宏和定义的标识符替换了。在运行阶段是无法调试的。
函数可以逐语句调试。
递归
宏不能递归 ,函数可以。