用内联函数取代宏
C++中支持内联函数为了消除原C语言中宏 和宏函数的缺点 保留其优点
关C语言于中的宏:
- 在C语言中 宏可以提高代码的执行效率 并使代码易于更改
- 编译器在预处理阶段将宏代码文本替换到宏的使用处
宏函数省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return等过程,提高了速度。节省了函数调用的开销。
但由于宏的文本替换特性,导致其容易出错
宏的使用常见错误
1.`#define MAX(a,b) (a) > (b) ? (a) : (b)
语句:res = MAX(i,j) + 2;
预处理后的结果为:res = (i) > (j) ? (i) : (j) + 2;
发生了优先级错误
这不是我们想要的结果。 要解决它可以在宏函数整体加()或者 do{…}while(0);
2.整体加括号也解决不了的错误
res = MAX(i++,j)
预处理后的结果为:
res = ((i++) > (j) ? (i++) : j;
i有可能被++ 两次。
3.宏是不可调试的 其代码在预处理期间就已经被文本替换了
4.宏函数不可以访问类的受保护成员
内联函数的调用机制
内联函数通过其自身的特殊机制保证了效率和安全
1.内联函数可调式 在程序的Debug版本中 内联函数没有真正内联
编译器像一般函数一样为其生成含有调试信息的可执行代码 在Release版本中内联函数才有可能真正产生内联。
2.调用一个内联函数时 编译器先检查调用是否正确(进行类型安全检查,或自动类型转换) 如果正确 内联函数的代码会直接替换函数调用的语句。从而像宏一样省去了函数调用的开销。
假如内联函数是成员函数 对象的地址this会被放在合适的地方。
3.内联函数是函数 可以操作它有权访问的类的数据成员。
4.产生内联后、编译器可以通过上下文优化技术优化代码 这种优化由于在普通函数体内脱离了调用环境的上下文而无法实现。
使用内联函数的注意
- inline关键字必须和函数的定义放在一起才起作用,尽量不要放在函数的声明上。
2.inline是一个申请式的关键字 好的编译器会让不适合内联的inline关键字修饰的函数不内联 适合内联的无inline关键字函数内联
3.函数执行体短小的函数适合做内联函数
内联不是“万灵丹”它以代码膨胀为代价消耗更多内存空间 省去函数调用的开销
4.以下情况不适合内联
1.函数体内代码比较长
2.函数体内出现递归 循环等使函数执行时间远远大于调用开销的情况。
3.有时构造 析构函数看起来执行体不大 但其实调用了基类成员或成员对象的构造函数 析构函数 也不行。
5.类内定义的成员函数一般被编译器搞成内联函数 所以尽量不要类内定义成员函数。
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define MAX(a,b) ((a)>(b)?(a):(b))
inline int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int a = 9;
int b = 8;
//MAX(a++, b);
printf("%d %d", a, b);
cout << max(a++, b) << endl;
cout << a;
system("pause");
return 0;
}