带参数的宏:
#define SQ(y) ((y)*(y))
函数:
int SQ(int y)
{
return y*y;
}
区别:
1 | 带参数宏 | 函数 |
---|---|---|
传参方面 | 宏展开仅仅是字符串的直接替换,不会对表达式进行计算 | 函数是参数(计算过后的值)的传递,参数是有数据类型的 |
运行时期 | 宏在编译之前进行(先用宏体替换宏名,在进行编译) | 函数是在编译之后执行时才调用的 |
内存占用情况 | 宏的参数不占内存空间,因为只做字符串的替换 | 函数调用是参数之间的传递,所以占用内存 |
空间开销情况 | 宏函数中不存在空间开销 | 函数调用需要空间开销,因为在函数调用时,它即要保存现场又要调到另一个函数调用中去执行,然后还要返回现场。 |
优缺点
宏:
- 优点:在预处理阶段完成,不占用编译时间,同时,省去了函数调用的开销,运行效率高
- 缺点:不进行类型检查,多次宏替换会导致代码体积变大,而且由于宏本质上是字符串替换,故可能会由于一些参数的副作用导致得出错误的结果。
参数副作用例如:
#define f(x) x+x
f(2)/2 我们预想的值为(2+2)/2=2,实际上f(2)的值为2+2/2 = 3
函数:
- 优点:没有带参数宏可能导致的副作用,进行类型检查,计算的正确性更有保证。
- 缺点:函数调用需要参数、返回地址等的入栈、出栈开销,效率比较低。