前言
在c语言里面,我们将一些短并且经常使用的计算写成宏而不是写成函数,这是因为函数在执行的时候会消耗一定空间和时间,降低效率。宏可以避免函数调用的开销,这些都是由预处理来实现的。值得一提的是,预处理是将文本直接复制到用的地方。
一、宏处理可能带来什么?
我们来看一下宏定义会带来怎样的危害?
#define ADD(x,y) x+y
int main(){
int ret=ADD(10,20)*10;
cout<<ret<<endl;
}
210
我们的目的是让10+20的值在乘10,理论上应该等于300,为什么会出现这样的情况呢?
#define ADD(x,y) x+y //宏定义是简单的进行文本替换
int main(){
int ret=ADD(10,20)*10;//将ADD(10,20)替换成 10+20,最后变成 10+20*10
cout<<ret<<endl;
}
这是因为宏定义是进行了简单的文本替换,为了避免上面的情况发生又能将宏定义的优点保留下来,C++引入了内联函数。下面就介绍内联函数吧。
二、内联函数的优点
内联函数保留宏定义的效率,又没有函数调用的开销,又可以像普通函数一样进行参和返回值的安全检验,又可以作为成员函数。
内联函数的使用:inline 返回类型 函数名(参数)
也就是在普通函数前加一个 inline。
注意:函数声明和函数实现必须放在一起,不然编译器就会把他当做普通函数。
inline int func(int a,int b){
return a+b;
}
int main(){
int ret=ADD(10,20)*10;//宏定义的本质是将代码(x+y )拷过来,将执行10+20*10
cout<<ret<<endl;//输出为210,
//为了解决这个问题,引入了内联函数
cout<<func(10,20)*10<<endl;
}
210
300
对比一下输出,内联函数的优点就展现出来了。
但是在内联函数的使用中也有着一定的限定。大概有以下这么几个:
1.c++中推荐使用内联函数取代宏定义。
2.内联函数在最终生成的代码中是没有定义的,C++编译器直接将函数体插入函数调用地方,内联函数木有普通函数额外开销(压栈,转跳,返回)。
3.因为内联函数在最后生成的代码中是没有定义的,所以内联函数的定义域可以理解成只在定义的文件里面,如在a.cpp里面定义了,在b.cpp里面就不能调用,只能在b.cpp里面重新写才能调用。
4.inline只是编译器的内联请求,c++编译器会对其有一些限制,以下这些情况编译器不会考虑进行内联请求:
存在任何形式的循环。
存在过多的条件判断。
函数体过大。
对函数进行取址操作。
因此,内联函数只是给了编译器一个请求,至于接不接受还得取决于编译器。编译器一般都会内联小的,短的,使用频率高的。