首页 > 其他分享 >内联函数(inline)

内联函数(inline)

时间:2024-07-01 10:19:39浏览次数:24  
标签:__ 头文件 函数 编译器 内联 inline

① 概念引入

多用于复用性强的函数(代码量较少具有特定功能的函数)

坏处:让你的代码上下文很臃肿(冗余)

好处:
    在复用性强的函数调用的时候直接插入函数代码段而不是进行函数跳转(编译器弄的),减少性能消耗提高运行效率。
    减少函数调用开销:函数调用涉及压栈、跳转等操作,会产生额外的(CPU性能+内存)开销。通过内联函数,避免了这些开销,直接将函数体插入到调用处,提高程序的执行效率。
    inline int Fun();
    inline int Fun()
    {
        printf("打开一个文件");   
        xxx 
    }
    int main()
    {
        Fun(); 
        Fun();
        Fun();    
        return 0;           
    }

② 内联函数的使用

项目框架确定,相对系统平台(编译平台)的框架比较精简(微型处理器MCU---项目框架)--内联函数
系统源码中也有出现过。服务器等比较大的项目框架

有没有内联主要看编译器环境的选择也要看编译器支不支持
建议内联:建议编译器在编译的时候启动内联变量
inline int fun(); 

强制内联:也是需要看编译器支不支持,__attribute__((always_inline)) 是编译器提供的,并不是C语言的语法提供
inline int __attribute__((always_inline)) fun();  

或者

__attribute__((al_inlineways)) inline int fun(); //让编译器强制内联

__attribute__((always_inline)) 是 GCC 特有的语法,并非标准 C 的一部分。因此,
使用这种方式时需要确保你的项目使用的编译器支持这个特性。

内联功能主要由编译器决定:
    根据不同编译版本:
        可以由多种写法:
            定义的时候写 :
            如果编译器版本不支持定义和声明都写,我们选择这一种,因为编译对于内联语法,在调用内联的时候需要去识别内联函数是否再再当前函数调用的.c里面
            声明的时候写
            声明和定义的时候写:提高可读性

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

inline 函数仅仅是一个对编译器的建议,所以最后能否真正内联,看编译器的意思,它如果认为函数不复杂,能在调用点展开,就会真正内联,并不是说声明了内联就会内联,声明内联只是一个“建议“而已。
    
inline 的使用是有所限制的,inline 只适合涵数体内代码简单的涵数使用,不能包含复杂的结构控制语句例如 while、switch,并且不能内联函数本身不能是直接递归函数(即,自己内部还调用自己的函数)。

④ 建议 inline 函数的定义放在头文件中

头文件不是用来函数声明吗?现在还要把函数的定义和封装写道头文件里面?
1)代码量少不会让头文件很臃肿
2)为内联函数要在调用点展开,所以编译器必须随处可见内联函数的定义,要不然就成了非内联函数的调用了。
所以,这要求每个调用了内联函数的文件都出现了该内联函数的定义。
解决方法就是定义在头文件中,然后#include这个头文件

⑤ 内联函数的使用理解

内联函数并不是那么好用。
只有当函数非常短小的时候它才能得到我们想要的效果。
如果函数并不是很短而且在很多地方都被调用的话,那么将会使得可执行体(编译出来的程序)的体积增大。 

⑥ 内联函数的考点

Ⅰ 内联函数的作用? 
Ⅱ 内联函数的优缺点?
Ⅲ 谈谈你对内联函数的理解?
    优缺点,说出你的理解:默认是建议内联而已,应用场景

标签:__,头文件,函数,编译器,内联,inline
From: https://www.cnblogs.com/hhail08/p/18277497

相关文章

  • 53、Flink 测试工具测试用户自定义函数详解
    1.测试用户自定义函数a)单元测试无状态、无时间限制的UDF示例:无状态的MapFunction。publicclassIncrementMapFunctionimplementsMapFunction<Long,Long>{@OverridepublicLongmap(Longrecord)throwsException{returnrecord+1;}......
  • Oracle PL / SQL 函数
    FUNCTION是返回值的PL/SQL块或方法,因此它可以在赋值的右侧使用。这里是一个例子:n_value:=to_number('123.45');由于FUNCTION返回一个值,因此也可以在SQL语句中使用它,如下例所示:selectto_number('1')fromdual;创建函数让我们创建一个无错的to_number()函数,而不......
  • 【AI 大模型】大模型应用架构 ( 业务架构 - AI Embedded、AI Copilot、AI Agent | 技
    文章目录一、大模型技术方向-大模型训练/大模型应用二、大模型应用-业务架构1、AIEmbedded模式2、AICopilot模式3、AIAgent模式三、大模型应用-技术架构1、提示词技术架构2、Agent+FunctionCalling技术架构3、RAG技术架构4、Fine-tuning微调技术......
  • 【Effective Python教程】(90个有效方法)笔记——第3章:函数——24:用None和docstring来描
    文章目录第3章:函数第24条用None和docstring来描述默认值会变的参数函数默认值的坑(函数的默认参数值只在定义函数时计算)解决方法:将函数默认参数值设为None,然后再在函数体中判断并初始化函数默认参数值设置为None的其他应用示例“函数默认参数值设置为None”与“函数参数......
  • Linux---open和close函数
    open:这是对文件权限的说明。注意:返回上一个工作目录:cd-close函数:关闭文件注意:在对C语言代码进行了修改时,必须要都运行的文件重新编译,然后在重新运行。不然,输出的结果不会发生改变。今日标语“努力不一定成功,但不努力一定不会成功。”......
  • 关于函数指针和结构体一起的用法
    想到单片机中的中断处理不好多样化,一直通过函数指针传递,今天想通过函数指针实现多样化,在中断中放一个要执行的函数指针,在外面可以改变此指针指向的函数。配合结构体的使用,感受到面向对象中class的存在了。typedefint(*pFunc)(int);//定义一个函数指针类型intadd(inta){......
  • c语言malloc、calloc 和 realloc动态分配内存函数的区别
    c语言malloc、calloc和realloc动态分配内存函数的区别malloc、calloc和realloc是C语言中用于动态内存分配的三个重要函数,它们之间有一些关键的区别。以下是这三个函数的区别,以分点表示和归纳的形式进行解释:内存来源和初始化:malloc:在堆上分配指定大小的内存块,但不进行初始化......
  • C++ : 如何用C语言实现C++的虚函数机制?
    前言在 googletest的源码中,看到gtest-matchers.h中实现的MatcherBase 类自定义了一个VTable,这种设计实现了一种类似于C++虚函数的机制。C++中的虚函数机制实质上就是通过这种方式实现的,本文用c语言自定义虚函数表VTable实现了一下virtual的功能,来深刻理解其机制。我们通过创......
  • NzN的C++之路--拷贝构造函数&&赋值运算符重载
    目录Part1拷贝构造函数一、概念二、特征Part2赋值运算符重载一、运算符重载二、赋值运算符重载三、前置++和后置++重载Part3const成员Part4 取地址及const取地址操作符重载 Part1拷贝构造函数一、概念        拷贝构造函数:只有单个形参,该形参......
  • Java开发者的神经网络进阶指南:深入探讨交叉熵损失函数
    前言今天来讲一下损失函数——交叉熵函数,什么是损失函数呢?大体就是真实与预测之间的差异,这个交叉熵(CrossEntropy)是Shannon信息论中一个重要概念,主要用于度量两个概率分布间的差异性信息。在信息论中,交叉熵是表示两个概率分布p,q的差异,其中p表示真实分布,q表示预测分布,那么\(......