内联函数
简介
内联函数是C++为了提高程序运行速度所做的一项改进。
内联函数与常规函数的区别在于:c++如何把它们组合到程序中。
编译过程的最终产品是可执行文件,由一组机器语言指令组成。操作系统将这些指令载入到计算机内存中,因此每条指令都有自己特定的内存地址。计算机随后逐步执行这些指令。遇到循环或者分支语句的时候,就会向前或者向后跳到特定的地址。
常规函数调用
简单的说——使程序跳到另一个地址(函数的地址),然后在函数结束的时候返回。
详细描述——执行到函数调用的指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数复制到堆栈,跳到标记函数起点的内存单元,执行函数代码(也许还将返回值放到寄存器中),然后跳回到地址被保存的指令处。来回跳跃并记录跳跃为止意味着以前使用函数时,需要一定的开销。
内联函数
内联函数的编译代码与其他程序代码“内联”起来。编译器将使用相应的函数代码来替换函数调用。对于内联代码,程序无需跳到另一个位置去执行代码,再跳回来。
优势:运行速度更快。
缺点:占用更多的内存。
使用
- 在函数声明前加上关键词inline
- 在函数定义前加上关键词inline
inline double square(double x){
return x*x;
}
从运行速度来看,如果不加inline,可能要2.+秒,如果加上了inline,只需要不到0.5s即可。
宏与内联
C语言使用预处理语句#define来提供宏——内联函数的原是实现。
来看一下宏的用法:
#define SQUARE(X) X*X
a = SQUARE(2);//得到4
b = SQUARE(2+3);//2+3*2+3=11
int k = 2;
c = SQUARE(k++);
#define SQUARE(X) ((X)*(X))
a = SQUARE(8);//得到4
b = SQUARE(2+3);//(2+3)*(2+3)=25
int k = 2;
c = SQUARE(k++);//(k++)*(k++)。将k先递增1,然后*,然后再递增。得到6
宏不能按值传递。
所以如果用内联函数来求square(k++)
,得到的是k*k
的结果,然后k
才递增,k=k+1。inline函数是可以按值递增。
突然发现一个很有趣的事
int k = 2;
cout<<(k++)*k<<" "<<k<<endl;
k = 2;
cout<<(k)*(k++)<<" "<<k<<endl;
k = 2;
cout<<(k++)*(k++)<<" "<<k<<endl;
输出的结果:
6 3
6 3
6 4
为什么最终得到的结果都是6呢,有待思考
最终的结论:跟不同编译器的优化相关