内联函数
关键字inline,inline是空间换时间,提高了程序效率但花费了更多空间。举个例子,下面是一段C语言代码:
void fun(int i)
{
return i*2;
}
int main()
{
int a = 4;
int b = fun(a);
}
假定以上C文件被编译器编译成的汇编代码如下:
_f_int:
add ax,@sp[-8] ;相当于ax = ax + 4
ret
_main:
add sp,#8 ;堆栈指针SP移动8个字节,空出来的8个字节分别存放a,b
mov ax,#4 ;将立即数4送往寄存器ax中
mov @sp[-8],ax ;将ax的值送往堆栈指针-8个字节的内存单元中,可以看做a = 4这一操作
mov ax,@sp[-8] ;将a的值赋值给ax
push ax ;将寄存器的内容压入栈中
call _f_int ;call会做两件事,先把下一条指令的地址压入栈中,再跳转到要执行的子程序
mov @sp[-4],ax ;将ax的值赋值给b
pop ax ;将函数中的临时变量i出栈
函数调用需要做如下事情:将函数参数压入栈中、将返回地址压入栈中、准备返回值、将所有以上入栈的内容出栈。为了提高效率,设置关键字inline告诉编译器这个一个声明而非定义,在调用这个被inline修饰的函数时会将代码直接嵌入到调用的地方。有点类似于宏定义,宏定义是在编译前对所有的内容进行替换不涉及类型检查,而内涵函数存在类型检查。内联函数经过编译不会生成obj文件。
通过加了inline关键字的函数编译后结果:
可以看到汇编代码不会执行部分入栈和出栈操作,从而提高了程序的效率。
普通函数与内联函数:
普通函数时通过跳转到函数体里面执行程序,会有一些入栈出栈等操作;内联函数就是将代码嵌入调用该函数的位置,每调用一次就嵌入一次,因此提高了程序执行效率但增大了内存空间,所以说是空间换时间的策略
通常在程序设计时要求.h文件存放函数声明,.cpp文件对函数进行定义。
//a.h
inline void f(int i, int j);
//a.cpp
#include "a.h"
void f(int i, int j)
{
cout << i << "," << j << endl;
}
//main.cpp
int main()
{
f(10,10);
return 0;
}
执行以上代码会出错:
解决方法:不需要a.cpp文件,将f内联函数的定义放在头文件中。
<br>
//a.h
#include <iostream>
using namespace std;
inline void f(int i, int j)
{
cout << i << "," << j << endl;
}
//main.cpp
#include "a.h"
int main()
{
f(10,10);
return 0;
}
结果:
总结:
1.内联函数采取的是空间换时间的策略。
2.通常函数代码只有2~3行或者是被重复调用的函数,可以添加inline关键字。
3.某些情况即使添加了inline,如果程序占用空间过大,编译器也不会将该函数看做是内联函数
参考:
浙江大学翁凯C++
C++ Primer Plus 第8章