Redian新闻
>
【C语言】内联函数总结

【C语言】内联函数总结

公众号新闻

内联函数定义

inline关键字是C99标准的型关键字,其作用是将函数展开,把函数的代码复制到每一个调用处。这样调用函数的过程就可以直接执行函数代码,而不发生跳转、压栈等一般性函数操作。可以节省时间,也会提高程序的执行速度。

为什么需要内联函数

在C语言中,如果一些函数被频繁的调用,不断地用函数入栈,即函数栈,则会造成栈空间或者栈内存的大量消耗,为了解决这个问题,特别的引入了inline关键字,表示为内联函数。栈空间指的是函数内数据的内存空间,在一个系统下,栈空间的资源是有限的,假如频繁大量的使用就会因栈空间的不足而导致出错,函数的死循坏递归调用的最终结果就是导致栈内存空间的枯竭。

#include <stdio.h>
//函数定义为inline即:内联函数
inline chardbtest(int a) {
    return (i % 2 > 0) ? "奇" : "偶";

 
int main()
{
   int i = 0;
   for (i=1; i < 100; i++) {
       printf("i:%d    奇偶性:%s /n", i, dbtest(i));    
   }
}

上面的例子就是标准的内联函数的用法,使用inline修饰带来的好处我们表面看不出来,其实,在内部的工作就是在每个for循环的内部任何调用dbtest(i)的地方都换成了(i % 2 > 0) ? "奇" : "偶",这样就避免了频繁调用函数对栈内存重复开辟所带来的消耗。

内联函数注意事项

  1. 关键字inline必须与函数的定义体放在一起,才能使函数成为内联函数,仅仅将inline放在函数声明前面不起作用

如下风格的函数fun则成为内联函数:

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

}
  1. 关键字inline的使用是有所限制的

inline只适合函数体内代码比较简单的函数使用,不能包含复杂的结构控制语句,例如while、switch,并且内联函数本身不能是直接递归函数(函数内部调用自己的函数)。

  1. inline仅是一个对编译器的建议

inline函数仅仅是一个对编译器的建议,所以最后能否真正内联,看编译器的意思,它如果认为函数不复杂,能在调用点展开,就会真正内联,并不是说声明了内联就会内联,声明内联只是一个建议而已。

  1. 建议:inline函数的定义放在头文件中

其次,因为内联函数要在调用点展开,所以编译器必须随处可见内联函数的定义,要不然就成了非内联函数的调用了。所以,这要求每个调用了内联函数的文件都出现了该内联函数的定义。因此,将内联函数的定义放在头文件里实现是合适的,省却你为每个文件实现一次的麻烦。声明跟定义要一致:如果在每个文件里都实现一次该内联函数的话,那么,最好保证每个定义都是一样的,否则,将会引起未定义的行为。如果不是每个文件里的定义都一样,那么,编译器展开的是哪一个,那要看具体的编译器而定。所以,最好将内联函数定义放在头文件中。

  1. static和inline联合使用

static是静态修饰符,由其关键字修饰的变量会保存到全局数据区,对于普通的局部变量或者全局变量,都是由系统自动分配内存的,并且当变量离开作用域的时候释放掉,而使用static关键字来修饰,只有当程序结束时候才会释放掉,使用static inline修饰时,函数仅在文件内部可见,不会污染命名空间,另外,函数在运行过程中也会分配内存空间,但是由于static的存在,就和修饰变量类似,它只会开辟一块内存空间。

内联函数优缺点

  1. 普通函数在调用过程中,会对寄存器中内容进行上下文切换(push和pop操作),而内联函数则不需要,所以普通函数相比内联函数,耗时要多一些
  2. 当函数使用次数比较多的时候,内联函数在每个调用的地方都会被展开,所以导致固件大小会变大,同一段代码会多次重复出现在固件中。而普通函数则没有此问题,不管调用的函数的次数多少,函数在固件中均只占用一处,空间利用率较高。inline函数其实就是空间换时间

inline 和宏的区别

虽然inline函数和带参数的宏很像,但是在使用方法上和宏还是有很大区别的:


inline()函数带参数的宏
展开的时机在编译的时候展开,因此inline关键字是一个编译关键字在预处理时展开,因此#define关键字是一个预处理关键字
参数类型检查inline()函数是一中函数,会进行严格的参数类型检查不会检查参数类型,只是做简单的字符串替换,因此在使用带参数的宏时会有一些副作用,编写程序是要人为预防
是否允许有复杂语句不允许出现复杂语句,如果出现复杂语句,该函数将不会展开,例如递归,大型循环等对此不做要求。宏只是做字符串替换操作,而不了解语句的含义
是否一定被展开不一定,是否展开由编译器决定一定,只要使用了宏就可以保证被展开
接口封装
是否支持调试

总结

  1. 内联函数相比宏函数,会进行语法检查。宏函数是在预处理阶段生效,内联函数是在编译阶段进行语法检查然后替换。
  2. 内联函数相比普通函数,少了上下文切换的步骤所以执行会更快一些。
  3. 内联函数被多次调用,会使固件大小膨胀,内联函数的高速是以空间来换时间。
  4. 内联函数不可递归。
  5. 如果函数内容太过于复杂,编译器会忽略inline关键字,把他当成普通函数来处理。

本文参考

https://zhuanlan.zhihu.com/p/448262183

https://zhuanlan.zhihu.com/p/50812510

https://cloud.tencent.com/developer/article/2224955

推荐阅读  点击标题可跳转

1、会写代码的总理!全球第一“开源”名门望族

2、全网最全网络基础思维导图(38张)

3、他潜伏三年想插它后门,最终还是输给了另一个他

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
官宣!用于485的语言成绩仅1年有效,学签 /485提高语言要求,23号就生效!来英国读语言?可以找个短租语言班房源过渡哦!价格更便宜!2024 年 3 月编程语言排行榜,Python 与其他语言之间的差距从未如此之大!英国语言班开启,快来看看12周语言、8周语言班的同学住哪里!Pylon框架:在PyTorch中实现带约束的损失函数LLM性能最高60%提升!谷歌ICLR 2024力作:让大语言模型学会「图的语言」【Church Park 2024新政策来袭!本科生不再需要额外支付10%|五星推荐!NEU,伯克利同学实现步行上学】Meta新模型NLLB获Nature盛赞,200种濒危语言高质量翻译,「不让任何语言掉队」全英语言班即将开启,快来看看读语言住哪里更便宜!全英语言班即将开始, 还没有预订短期语言班公寓的同学可以快来看看哦...这就是OpenAI神秘的Q*?斯坦福:语言模型就是Q函数AI 是个很长的故事【天玉之浪漫爱情诗歌五十首】(2016-2018)英国语言班即将开始 | 快来看看自己的语言班同学都住哪里!英国语言班即将开始,快来看看你的语言班同学都住哪里?谁他妈没织过毛衣——李志英国语言不要IELTS就可以申请?可以直接来参加语言班咯...快来看看住哪里便宜!匪夷所思的2020年代 - 亡羊补牢,为时未晚全英语言班即将开启,快来看看你们20周、18周、16周语言班的同学住哪里?来英国读语言,不知道住哪?看看这些短租房源吧,更适合读语言的你!伦敦暑期语言班即将开启,快来看看伦敦的同学读语言、短租、旅游都可以住哪里?突发!UCL这些本科语言班已满位!语言没过con,怎么办?全英语言班转租房源招租啦 | 快来看看有没有适合你的房源哦...找个转租读语言,更具性价比!深圳/香港/上海内推 | 商汤研究院基础语言模型团队招聘大语言模型算法研究员全英语言班即将开始,快来看看来英国读语言可以住哪里最便宜!!!Go 的函数,方法和接口最新研究:大模型已涌现出欺骗能力!钻漏洞、偷偷篡改奖励函数,GPT-4欺骗人类高达99.16%英国语言班即将开启,短期语言班住哪里?快来看看语言班同学都住哪!Linus眼中“很烂”的C++击败了C语言全英语言班即将开启,快来看看这些便宜的语言班房源吧,寻找一个语言班搭子!北航等提出超大规模多语言代码评测基准,涵盖40种编程语言全英语言班即将开始,快来看看有没有便宜的语言班房源可以入手的!鹰鸮弗拉科的自由之旅全英语言班房源持续招租中...快来看看有没有适合你的短租语言班房源!报名开启!北京语言大学语言智能2024年全国优秀大学生暑期夏令营
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。