赞
踩
【注:本文只讨论C语言中的内联函数,暂不谈论C++,因为C++中这块知识相对要更复杂。】
在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗。
为了解决这个问题,特别的引入了inline修饰符,表示为内联函数。
内联函数是代码被插入到调用者代码处的函数。内联函数通过避免被调用的开销来提高执行效率。
采用内联函数实质是以空间换时间的做法
举例:
void myprintf(int a)
{
printf(“%d”,a);
}
int main()
{
for(i=0;i<100;i++)
myprintf(i);
}
对于这个函数,在进行反复的打印i的过程中我们是不是要反复的调用myprintf()这个函数,进函数和出函数是需要时间的(入栈出栈),假设这个过程用时为4ms,而执行printf这个操作只需要2ms,那么在100次循环的过程中进出函数的时间比函数功能printf需要的时间还要长,这样很影响工作效率。于是,我们就想要如何避免进出函数的过程呢?可以声明inline这个关键字。
inline void myprintf(int a)
{
printf(“%d”,a);
}
int main()
{
for(i=0;i<100;i++)
myprintf(i);
}
main函数中的myprintf(i);会直接替换成该函数主体,上面的代码在编译时实际上是这样的:
inline void myprintf(int a)
{
printf(“%d”,a);
}
int main()
{
for(i=0;i<100;i++)
{
printf(“%d”,i);
}
}
内联函数看上去和宏定义非常相似。
对于上面的例子,我们可以用宏定义实现:
#define MYPRINTF(a) printf(“%d”,a);
int main()
{
for(i=0;i<100;i++)
MYPRINTF(i);
}
效果可以说与前面使用内联的方式没多大差别。
但宏定义在某些情况下会有问题,比如:
// 返回 i 的绝对值的宏 #define abs1(i) \ ( (i) >= 0 ? (i) : -(i) ) // 返回 i 的绝对值的内联函数 inline int abs2(int i) { return i >= 0 ? i : -i; } int fun(); void userCode(int x) { int ans; ans = abs1(x++); // 错误!x 被增加两次 ans = abs1(fun()); // 错误!fun()被调用两次 ans = abs2(x++); // 正确! x 被增加一次 ans = abs2(fun()); // 正确! fun() 被调用一次 }
ans = abs1(x++); 展开是ans = ( (x++) >= 0 ? (x++) : -(x++) );
所以x++会执行2次,这可能是用户所不希望的。
而内联函数,与直接的函数调用区别仅在于没有函数调用过程的消耗。保留了函数调用的特性,又提高函数的执行效率。
和宏不同的,还有内联函数的参数类型被检查,并且被正确地进行必要的类型转换。
1、inline只适合函数体内代码量少的函数使用,因为每一处内联函数的调用都要复制代码,如果该函数代码量较大,将使程序的总代码量增大,消耗更多的内存空间。
2、内联函数本身不能是直接递归函数(自己内部还调用自己的函数)。因为这样会在编译时无穷无尽地展开。
3、如果执行函数体内代码的时间,相比于函数调用的时间开销较大,那么使用内联的效率的收获会很少。比如函数内有循环,这种情况就不考虑用内联函数了。
4、关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。
inline void Foo(int x, int y); // inline 仅与函数声明放在一起
void Foo(int x, int y)
{
}
5、对于功能复杂,内容较多的函数,即使加上inline修饰符,也不一定能作为内联函数,因为编译器会判定做优化。
static inline的内联函数,一般情况下不会产生函数本身的代码,而是全部被嵌入在被调用的地方。如果不加static,则表示该函数有可能会被其他编译单元所调用,所以一定会产生函数本身的代码。所以加了static,一般可令可执行文件变小。—【存疑,不确定】
static inline的内联函数,只能在本文件内调用,而没有static则可以被其他文件调用,这与static的常用方法一致。
函数的地址被使用的时候。如通过函数指针对函数进行了间接调用。这种情况下就不得不为static inline函数生成独立的汇编码,否则它没有自己的地址。
参考鸣谢:
https://blog.csdn.net/zqixiao_09/article/details/50877383
https://www.cnblogs.com/linux-bfbdxj520/p/11405474.html
https://www.jb51.net/article/41520.htm
https://blog.csdn.net/chuqierliang/article/details/48053417
https://blog.csdn.net/weixin_33895657/article/details/92037511
https://blog.csdn.net/qq_33757398/article/details/81390151
https://blog.csdn.net/weixin_30706507/article/details/96192546
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。