记得早先少年时
大家诚诚恳恳
说一句 是一句
清早上火车站
长街黑暗无行人
卖豆浆的小店冒着热气
从前的日色变得慢
车,马,邮件都慢
一生只够爱一个人
从前的锁也好看
钥匙精美有样子
你锁了 人家就懂了
木心 – 《从前慢 》

一、inline 为何诞生?

在使用 C 语言进行编程时,如果有一些函数被频繁调用,就会不断地有函数跳转的操作,随之也会频繁带来入栈、出栈等操作,不经影响效率,还会大量占用栈等空间。

如何解决这个问题?我们可以选择用类似的代码段直接实现该函数功能,这样就不存在函数调用带来的各种问题了,但是当大规模使用该功能时,我们就得在每处需要的地方重复实现该代码段。面对着两难问题,该如何选择呢?

小孩子才做选择,当然是全都要。

本期主角 inline 修饰符就此登上历史舞台,使用 inline 修饰的函数,被称为内联函数。
内联函数有着函数可以方便被重复调用的优点,也有能让函数运行效率大大提高的优点,但是它也不是完美无瑕,也有其弱点,官方说法就是有其局限性,这个我们后面会提到。

二、内联函数的使用

关键字 inline 与函数定义体放在一起就能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。
如下风格的函数Foo 则成为内联函数:

void Foo(int x, int y);
inline void Foo(int x, int y) // inline 与函数定义体放在一起
{}

由此,我们可以看出 inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。

第一节,提到了 inline 诞生的背景,有提到了具有函数能够多次被调用的优点,至于如何让函数执行地更优效率呢?
其实 “内联” 二字就说清楚,函数在编译的时候,会将调用内联函数的部分直接用代码段替代,这其实和宏很像,但是本质上还是函数,可以理解为函数实体直接嵌入在调用的地方,这一点类似宏,所以运行效率特别高,这样就不会存在函数跳转、出栈入栈的操作了,缺点就是占用空间比较大。说明白了,其实就是一种用空间换时间的策略,我们用冗余的代码段的空间换取函数跳转系列操作的时间。

  • 一般内联函数是在 .h 的文件中调用,形式如下:

    static inline void Foo(int x, int y) // inline 与函数定义体放在一起
    {}
    

    这样定义的话,只要包含该头文件,就可以直接使用该内联函数。
    至于这里为什么要使用 static 的关键字呢?
    因为如果你在多个 .c 文件中包含实现内联函数的头文件,意味着每个 .c文件都定义了这个函数,就会造成函数重定义的错误,所以需要加上 static 来限定其作用范围,避免提示重复定义的错误。

  • 如果是在 .c 文件下定义和使用内联函数,是否需要 static 呢?
    答案是最好写上,不然容易出现错误,原因如下:

    正确情况下,是如果在非优化的情况下,inline 需要配合 static 或者 extern 才能够编译。而在优化情况下,inline 可以单独使用。为什么会这样呢?
    实际上,在 C17 标准中我们使用的 inline 关键字来源于 C99 标准。而在这个标准中,仅带有 inline 的函数具有 inline definition,表明该函数定义仅用于内联。而在非优化情况下,编译器通常会去寻找对应符号的 external definition(可以通过添加 extern 而获得),因此这种情况下会出现 linker error。而通过添加 static 关键字,可以使得对应函数定义具有 internal linkage,从而被编译器使用。在优化情况下,编译器会直接使用 inline definition 进行内联。
    具体可以参考标准:http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf(112页,6.7.4.6)
    – 来自极客时间《深入 C 语言和程序运行原理》第一讲,评论区老师的回复。

三、使用内联函数的局限性

  • inline 只适合函数体内代码简单的函数使用,不能包含复杂的结构控制语句例如while、switch,并且内联函数本身不能是直接递归函数。
  • 内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。所以这是一个取舍问题,一般被频繁调用且代码简单的函数才会设定为内联函数。
  • 使用 inline 修饰的函数最终不一定会成为内联函数,使用 inline 只是相当于给编译器一个建议,编译器将会根据函数的定义体,自动地取消不值得的内联,所以是否实现内联函数,由编译器最终决定。(通过查看函数对应的汇编实现可以知道是否实现内联)

四、参考资料

  • 内联函数 —— C 中关键字 inline 用法解析
  • static关键字的作用_详解static inline关键字

更多精彩内容,请关注公众号《嵌入式小散修》

【C语言内功心法】inline -- 提高函数的运行效率相关推荐

  1. 将python代码转化为c语言代码,提高运行效率

    将python代码转化为c语言代码,提高运行效率 首先,需要安装cpython库: pip install cython 安装完成之后,写一段简单的代码,例如下面这个利用递归求斐波那契数列的函数,然后 ...

  2. C语言中内联函数的作用 inline

    C语言中内联函数的作用 inline C语言中内联函数到底有什么作用? 试想一下,每当我们在假设就在主函数中调用另外一个函数的时候,那么这个函数就要入栈或者出栈,比如说下面的一个例子: 点击(此处)折 ...

  3. C语言及程序设计提高例程-10 调试技术:进入函数内部去

    贺老师教学链接  C语言及程序设计提高 本课讲解 老革命遇上新问题(哪错了?) #include <stdio.h> float max(float x, float y); int ma ...

  4. python以运行效率高著称吗_如何提高python的运行效率

    展开全部 窍门一:关键代码使用外部功能包 Python简化了许多编程任务,但是32313133353236313431303231363533e78988e69d8331333363393566对于一 ...

  5. C++内联(inline)函数

    内联函数 内联函数是一种特殊类型的函数,内联函数在定义或声明时前面加上"inline"关键字.比如: inline int max(int a,int b) { return (a ...

  6. c++语言中如果调用函数时,需要改变实参或者返回多个值,应该采取,C++综合练习题2...

    C++程序设计综合练习题(二) 一.单项选择题 1. 静态成员函数没有() A. 返回值 B. this指针 C. 指针参数 D. 返回类型 2. 假定AB为一个类,则执行"AB a(2), ...

  7. python提高运行效率_如何提高Python的运行效率 | 萧小寒

    摘要 在我们开发的过程中,提高程序的运行效率是必不可少的一个环节.多人实现同一个功能,往往给出的代码也不尽相同.在这些成品代码中,有些人写的代码运行效率高,有些人写的代码运行低.其中原因,只有很少一部 ...

  8. 如何让matlab全速运行,提高matlab代码运行效率

    提高matlab代码运行效率 Matlab是一种解释性语言,追求的是方便性.灵活性以及交互性,因此在快速性上要比C语言这种性能强劲著称的稍逊一筹.然而,通过一些手段,我们也能让MATLAB语言快起来, ...

  9. C语言的内联函数的作用

    关内联函数键字inline void myprintf(int a) { priintf("%d",a); } int main() { for(i=0;i<100;i++) ...

最新文章

  1. 1.5 测试php解析
  2. c\c++ 随机数函数
  3. HashMap类Compute方法详解及样例
  4. CSDN markdown 如何更改文字字体、样式、颜色、大小?
  5. 【Docker】 安装 nexus3
  6. EF中的那些批量操作
  7. 在 Go 语言中,如何正确的使用并发
  8. 如何修改SharePoint服务器场管理员帐户和密码
  9. ?php $postsperpage=9;?,php – 如何在自定义WP_Query Ajax上实现分页
  10. A*算法一个简单的记录
  11. 抖音封禁超万账号;小米回应手机壳含毒;百度网盘封杀非官方版 | CSDN极客头条
  12. 转:在windows中将tree命令加入git-bash中
  13. Java编译器 iOS_Java编译器
  14. 微信公众号支付完整流程
  15. tensorflow sess.run()
  16. .net企业实战视频就业培训
  17. 「BZOJ4763」雪辉
  18. 洪柱森老师介绍--沪师经纪-刘建
  19. php html5定位,HTML HTML5 地理定位 - 闪电教程JSRUN
  20. 台式计算机32位和64位的区别,电脑操作系统中32位和64位到底有哪些区别?

热门文章

  1. ORB(FAST+BRIEF)特征提取与实现——特征点提取算法分析
  2. halcon拟合直线
  3. UniverSeg:通用医学图像分割模型来了!
  4. 通信网络中的数据透传
  5. 武汉大学计算机学院乒乓球室,武汉大学2018年研究生乒乓球比赛报名
  6. PV操作每日一题-黑白棋子问题(变式)
  7. 通过VCP(VMware Certified Professional)认证
  8. 读过《坏孩子的故事》后
  9. 做题记录(2019年2月10日起)
  10. 匹配手机和小灵通的正则表达式