内联函数
函数调用是有时间和空间开销的。程序在执行一个函数之前需要将实参、局部变量、返回地址以及若干寄存器都压入栈中,然后才能执行函数体中的代码;执行完之后,还要将之前压入栈中的数据都出栈,才能接着执行函数调用位置以后的代码。
如果函数体代码比较多,需要较长的执行时间,那么函数调用机制占用的时间可以忽略;如果函数只有一两句语句,那么大部分的时间都会花费在函数调用机制上,这种时间开销就不容忽视。
为了消除函数调用的时空开销,C++在编译时将函数调用处用函数体替换,即内联函数。
注意:要在函数定义出添加inline关键字,在函数声明处添加inline关键字是无效的。
#include <iostream>
using namespace std;
//内联函数,交换两个数的值
inline void swap(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main(){
int m, n;
cin>>m>>n;
cout<<m<<", "<<n<<endl;
//编译器遇到函数调用swap(&m, &n)时,会用swap()函数体中的代码替换swap(&m,&n),同时用实参代替形参。
swap(&m, &n);
cout<<m<<", "<<n<<endl;
return 0;
}
内联函数的缺点:编译后的程序会存在多份相同的函数拷贝。
注意:对函数做inline声明只是程序员对编译器的一个建议,而不是强制性的。编译器有自己的判断能力,它会根据具体情况做决定。
使用内联函数替换带参数的宏
和宏一样,内联函数可以定义在头文件中(不用加static关键字),并且头文件被多次#include后也不会引发重复定义错误。
内联函数在编译时会将函数调用处用函数体替换,编译完成后函数就不存在了,所以在链接时不会引发重复定义错误。
这一点和宏很像,宏在预处理时被展开,编译时就不存在了。从这个角度讲,内联函数更像编译期间的宏。
内联函数的两个作用:一是消除函数调用时的开销,二是取代带参数的宏。
如何规范的使用内联函数
从代码重复利用的角度讲,内联函数已经不再是函数了。因为内联函数的代码在编译后就被消除了,不存在于虚拟地址空间中,没法重复使用。
在多文件编程时,建议将内联函数的定义直接放在头文件中,并且禁用内联函数的声明