深入理解C++内联函数

 更新时间:2022年01月11日 16:23:04   作者:Enjoy solitude-  
这篇文章主要为大家介绍了C++内联函数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

内联函数的概念

inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数的使用可以提升程序的运行效率。

举个例子:

在C++中我们通常定义以下函数来求两个整数的最大值:

代码如下:

int max(int a, int b) 
{ 
 return a > b ? a : b; 
} 

为这么一个小的操作定义一个函数的好处有:

  • 阅读和理解函数 max 的调用,要比读一条等价的条件表达式并解释它的含义要容易得多
  • 如果需要做任何修改,修改函数要比找出并修改每一处等价表达式容易得多
  • 使用函数可以确保统一的行为,每个测试都保证以相同的方式实现
  • 函数可以重用,不必为其他应用程序重写代码

虽然有这么多好处,但是写成函数有一个潜在的缺点:调用函数比求解等价表达式要慢得多。在大多数的机器上,调用函数都要做很多工作:

- 程序需要存储当前地址,以便调用结束后返回继续执行
- 程序将传入函数的参数压栈
- 程序跳到跳到标记函数起点的内存单元,执行函数代码
- 函数调用结束后,将栈清空,返回到之前存储的地址继续执行

C++中支持内联函数,其目的是为了提高函数的执行效率,用关键字 inline 放在函数定义(注意是定义而非声明)的前面即可将函数指定为内联函数,内联函数通常就是将它在程序中的每个调用点上“内联地”展开,相当于直接copy一份函数体内代码,在执行到的时候直接按照代码顺序执行,省去了许多函数调用过程,节省了时间。

假设我们将 max 定义为内联函数:

代码如下:

inline int max(int a, int b) 
{ 
 return a > b ? a : b; 
} 
则调用: cout<<max(a, b)<<endl;


在编译时展开为: cout<<(a > b ? a : b)<<endl;

从而消除了把 max写成函数的额外执行开销

是不是觉得这和有些像?那为什么不直接用宏?还要整个内联函数

内联函数和宏

首先,宏能够表达的意思有限,通常是一行的表达式。其次,用宏的安全性不高,容易出错。

假设定义宏如下:

#define MAX(a,b)  a>b?:a:b

那么语句

res = MAX(i,j)+2;

会被预处理器扩展为

res = i > j? i:j+2;

由于+的优先级高于?,因此最终比较结果与我们期望不符。
那如果把宏修改为

#define MAX(a,b) (i &gt; j? i:j)

仍然存在问题,例如

res = MAX(i++,j)
res = (i++ < j? i++:j);  // i被+了两次

同时,宏无法调试,但内联函数可以。在程序的调试版本,内联函数并没有真正内联,就像普通函数一样实现调试,在程序的发行版本,编译器才会实现真正内联。

无论是《Effective C++》中的 “Prefer consts,enums,and inlines to #defines” 条款,还是《高质量程序设计指南——C++/C语言》中的“用函数内联取代宏”,宏在C++中基本是被废了。

内联函数的特性

1、inline是一种以空间换时间的做法,省了去调用函数的额外开销。由于内联函数会在调用的位置展开,所以代码很长或者有递归的函数不适宜作为内联函数。频繁调用的小函数建议定义成内联函数。

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

3、inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了链接就会找不到。

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

5 .相比于宏,有类型检查,安全性更高,具有一般函数特性,可调试。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • QT实现简单打地鼠游戏

    QT实现简单打地鼠游戏

    这篇文章主要为大家详细介绍了QT实现简单打地鼠游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • C语言冒泡排序超全面实现流程

    C语言冒泡排序超全面实现流程

    算法中排序是十分重要的,而每一个学习计算机的都会在初期的时候接触到这种排序,下面这篇文章主要给大家介绍了关于c语言冒泡排序的相关资料,需要的朋友可以参考下
    2023-01-01
  • 从头学习C语言之if语句的使用

    从头学习C语言之if语句的使用

    这篇文章主要为大家详细介绍了C语言之if语句的使用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • C++ Cartographer源码中关于Sensor的数据走向深扒

    C++ Cartographer源码中关于Sensor的数据走向深扒

    这篇文章主要介绍了C++ Cartographer源码中关于Sensor的数据走向,整个Cartographer源码阅读是很枯燥的, 但绝对是可以学到东西的,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-03-03
  • C语言实现随机抽取纸牌程序

    C语言实现随机抽取纸牌程序

    这篇文章主要为大家详细介绍了C语言实现随机抽取纸牌程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • C语言实现递归版扫雷游戏实例

    C语言实现递归版扫雷游戏实例

    大家好,本篇文章主要讲的是C语言实现递归版扫雷游戏实例,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • QT利用QPdfWriter实现绘制PDF(支持表单输出)

    QT利用QPdfWriter实现绘制PDF(支持表单输出)

    这篇文章主要为大家详细介绍了QT如何利用QPdfWriter实现绘制PDF,并可以支持表单输出。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-01-01
  • Qt串口通信开发之QSerialPort模块详细使用方法与实例

    Qt串口通信开发之QSerialPort模块详细使用方法与实例

    这篇文章主要介绍了Qt串口通信开发之QSerialPort模块详细使用方法与实例,需要的朋友可以参考下
    2020-03-03
  • OpenCV实现鼠标在图像上框选单目标和多目标

    OpenCV实现鼠标在图像上框选单目标和多目标

    这篇文章主要为大家详细介绍了OpenCV实现鼠标在图像上框选单目标和多目标,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • 详解C++编程中类的成员变量和成员函数的相关知识

    详解C++编程中类的成员变量和成员函数的相关知识

    这篇文章主要介绍了C++编程中类的成员变量和成员函数的相关知识,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09

最新评论