• 内联函数详解


    前言

    这里vince将要进入C++的学习了,C++学习将是一个漫长的过程,当然在学习这里的基础上前面的知识也不能不复习。也有很多人说C++有多难有多难的,但是我们不能胆怯,努力去学,孰能生巧,至少能够达到了解它的层次哈~
    在这里插入图片描述

    正文

    知识点一:内联

    1、内联函数的诞生

    为什么C++里面会引入内联呢?
    答:为了解决频繁短小函数的调用,此时会使用内联函数。
    大家回想一下C语言里面怎样解决短小函数频繁调用的?
    答:在C里面我们是利用宏来解决短小函数频繁调用的。

    说到这里,大家可以自己尝试写一个实现宏函数吧!
    例:(求和的宏函数定义)

    //#define ADD(x, y) return x + y;
    //#define ADD(x, y) (x + y);
    //#define ADD(x, y) x + y
    //以上这都是错误写法,宏函数很容易写错
    //宏还不支持调试
    
    //验证自己宏写的是否正确,就是去替换验证一下
    #define ADD(x, y) ((x)+(y))   //正确写法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    哈哈哈~我相信以上宏写法的这些错误,肯定有不少人犯错吧。瞧瞧这就是宏,不但写的时候复杂容易出错之外,还晦涩难懂,不易理解并且也不支持调试。

    因此C++就进行改进完善,引出了内联函数,来解决宏函数晦涩难懂,容易写错的问题。


    2、内联函数概念

    在函数声明或者定义的时候,以关键字inline修饰的函数就叫做内联函数。
    例:(求两数之和的函数inline())

    #include 
    using namespace std;
    inline int Add(int x = 10, int y = 8)//inline修饰的Add函数
    {
    	return x + y;
    }
    int main()
    {
    	int ret1 = Add(8, 24);
    	int ret2 = Add(2, 4);
    	int ret3 = Add(5, 6);
    	cout << ret1 << " " << ret2 << " " << ret3 << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    运行结果
    在这里插入图片描述


    3、内联函数的特性

    .1、inline是一种以空间换时间的做法,省去调用函数额外开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。

    内联函数的声明、定义和调用方法与普通函数相同,但是C++里面对他们的处理方式不同。如果一个函数被定义为内联函数,在编译的时候,C++将用内联函数的代码代替对它这个函数的每次调用。
    上面main函数里面多次调用内联函数Add(),C++编译器在编译此程序的时候,会对main函数中的函数做如下处理:

    int main()
    {
    	int ret1 = 8 + 24;
    	int ret2 = 2 + 4;
    	int ret3 = 5 + 6;
    	cout << ret1 << " " << ret2 << " " << ret3 << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里就可以看出,在需要调用Add()函数的时候,没有去调用Add()函数,而是直接使用Add()函数中的代码逻辑实现。

    我们来看看不加inline时候,就会有函数压栈的开销:(运行环境为vs2019)
    下图在Debug版本下可以看到汇编代码,这里call Add就是对Add函数的调用,此时需要有函数压栈开销。
    在这里插入图片描述如果在上述函数前增加inline关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。
    这里在Debug版本下需要配置一下环境才可以看到
    在这里插入图片描述
    Debug版本配置环境补充说明:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    这里可以看出加inline后就会去掉函数压栈开销,从而提升程序自身效率。这就是一种以空间换时间的做法。

    2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。

    3. inline函数的声明或定义必须在函数的调用之前完成。

    例:

    #include 
    using namespace std;
    
    inline int Add(int x = 10, int y = 8);//声明Add是内联函数
    
    int Add(int x, int y)//可以在这里前面加上inline,也可以省略(声明的时候添加了),意义都相同
    {
    	return x + y;
    }
    int main()
    {
    	int ret = 0;
    	ret = Add();
    	cout << ret << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    分析:
    该程序中,Add函数在声明的时候冠以关键字inline,而定义的时候没有冠以关键字inline,但仍是内联函数。
    错误示例:

    #include 
    using namespace std;
    
    int Add(int x = 10, int y = 8);//声明不给inline,Add是一个普通函数
    int main()
    {
    	int ret = 0;
    	ret = Add();
    	cout << ret << endl;
    	return 0;
    }
    inline int Add(int x, int y)//定义的时候给inline
    {
    	return x + y;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    分析:
    这里Add()函数在声明的时候没有给关键字inline,即声明Add()是一个普通函数,此时在main函数里面调用Add()时候,编译器就会先去找他的声明,根据声明确定它为一个普通函数,因此,尽管在定义的时候有inline但是,此时编译器也无法识别。
    在这里插入图片描述

    结语

    vince刚刚入坑CPP,这里是CPP的一部分基础学习,好多人都说CPP最难,其实什么事对于初学者来说都难,但是只要我们能够坚持学习,就一定会有进步的哈~希望我和大家都不要放弃!。

    如果各位大佬们觉得有一定帮助的话,就来个赞和收藏吧,如有不足之处也请批评指正


    代码不负有心人,98加满,向前冲啊🐬

    以上代码均可运行,编译环境为 vs2019哈~

  • 相关阅读:
    TypeScript算法题实战——字符串篇(字符串的反转、旋转、查询、KMP算法)
    ModelSim® SE Command Reference Manual : find命令的用法
    【JavaScript——流程控制的详解】
    Apache SeaTunnel Web 功能正式发布!
    STM32时钟系统
    基于Redis的简易延时队列
    Debain JDK8 安装
    软件测试 - 软件测试流程(完整版)避免当背锅侠,测试人的生存......
    flutter 使用texture实现Linux渲染视频
    DataHub元数据采集
  • 原文地址:https://blog.csdn.net/m0_56817529/article/details/127920665