1.inline 函数

1.1定义:inline 函数由 inline 关键字定义,当函数功能简单,使用评率高,为了提高效率,直接将函数的代码嵌入到程序中。但缺点是:(1)相同代码重复书写;(2)程序可读性往往没有使用函数的好。 为了进一步协调效率和可读性之间的矛盾,c++提供了另一种方法,即定义内联函数,方法是在定义函数时加修饰词inline.

intline bool IsNumber(char ch)

{

return ch>='0'&&ch<='9'?1:0;

}

加inline关键字将其改写成内联函数,在编译期间编译器能够在调用点内联展开该函数。

实例:

在debug模式下,设置编译器。

 注意:

        inline是一种以空间换时间的做法,省去调用函数额开销,但当函数体的代码过长或者是递归函数,即使是加上inline关键字,也不会在调用点以内联展开该函数。

inline对编译器而言,仅仅只是一个建议,编译器会自动优化。

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

1.2编译器对 inline 函数的处理办法
    编译器在编译阶段完成对 inline 函数的处理,即对 inline 函数的调用替换为函数的本体。但 inline 关键字对编译器只是一种建议,编译器可以这样去做,也可以不去做。从逻辑上来说,编译器对 inline 函数的处理步骤一般如下:
(1)将 inline 函数体复制到inline函数调用处;
(2)为所用 inline 函数中的局部变量分配内存空间;
(3)将 inline 函数的的输入参数和返回值映射到调用方法的局部变量空间中;
(4)如果 inline 函数有多个返回点,将其转变为 inline 函数代码块末尾的分支(使用GOTO)。inline 通过消除调用开销来提升性能。

3.inline 函数使用的一般方法
   函数定义时,在返回类型前加上关键字 inline 即把函数指定为内联,函数申明时可加也可不加。使用格式为:inline int functionName(int first, int secend,...) {/****/};
4.inline 函数的优点与缺点
inline函数相对宏函数有如下优点:
(1)内联函数同宏函数一样将在被调用处进行代码展开,省去了参数压栈、栈帧开辟与回收,结果返回等,从而提高程序运行速度。

(2)内联函数相比宏函数来说,在代码展开时,会做安全检查或自动类型转换(同普通函数),而宏定义则不会。
例如:

#define MAX(a,b) ((a)>(b)?(a):(b))//宏函数

inline int MAX(int a,int b)//内联函数
{
    return a>b?a:b;
}

使用宏函数时,其书写语法也较为苛刻,如果对宏函数出现如下错误的调用MAX(a,"Hello"); 宏函数会错误地比较int和字符串,没有参数类型检查,但是使用内联函数的时候,会出现类型不匹配的编译错误。

(3)在类中声明同时定义的成员函数,自动转化为内联函数,因此内联函数可以访问类的成员变量,宏定义则不能。

(4)内联函数在运行时可调试,而宏定义不可以。

inline函数的缺点
(1)代码膨胀。
inline函数带来的运行效率是典型的以空间换时间的做法。

(2)inline 函数无法随着函数库升级而升级。
如果f是函数库中的一个inline函数,使用它的用户会将f函数实体编译到他们的程序中。

(3)是否内联,程序员不可控。
inline函数只是对编译器的建议,是否对函数内联,决定权在于编译器。

5.inline函数的注意事项

(1)使用函数指针调用内联函数将会导致内联失败。
也就是说,如果使用函数指针来调用内联函数,那么就需要获取inline函数的地址。如果要取得一个inline函数的地址,编译器就必须为此函数产生一个函数实体,那么就内联失败。

(2)如果函数体代码过长或者有多重循环语句,if或witch分支语句或递归时,不宜用内联。

(3)类的 constructors、destructors 和虚函数往往不是 inline 函数的最佳选择。
类的构造函数(constructors)可能需要调用父类的构造函数,析构函数同样可能需要调用父类的析构函数,二者背后隐藏着大量的代码,不适合作为inline函数。虚函数(destructors)往往是运行时确定的,而inline是在编译时进行的,所以内联虚函数往往无效。如果直接用类的对象来使用虚函数,那么对有的编译器而言,也可起到优化作用。

(4)至于内联函数是定义在头文件还是源文件的建议。
内联展开是在编译时进行的,只有链接的时候源文件之间才有关系。所以内联要想跨源文件必须把实现写在头文件里。如果一个 inline 函数会在多个源文件中被用到,那么必须把它定义在头文件中。
(5)能否强制编译器进行内联操作?
也有人可能会觉得能否强制编译器进行函数内联,而不是建议编译器进行内联呢?很不幸的是目前还不能强制编译器进行函数内联,如果使用的是 MS VC++, 注意 __forceinline 如同 inine 一样,也是一个用词不当的表现,它只是对编译器的建议比inline更加强烈,并不能强制编译器进行inline操作。

6.小结

inline函数与普通函数的比较

普通函数有开栈和清栈,inline函数无开栈和清栈。

当执行开销(代码小)< 调用开销(开栈)时,建议用inline

当执行开销(代码小)> 调用开销(开栈)时,不建议使用inline

inline和static 的区别

(1)内联函数没有开栈清栈的开销,static函数有;

(2)inline编译阶段代码展开导致函数本文件可见,而static是因为符号属性为local本文件可见。

inline和宏的区别

(1)inline编译时处理有类型检查,安全检查和语法判断等功能,宏预编译时处理无类型检查和安全检查,只是简单的替换

(2)宏无法调试,而内联可以进行调试。

(3)内联比宏更加安全,是一种更加安全的宏

(4) 内联函数在编译时展开,带参的宏在预编译时展开

内联函数直接嵌入到目标函数代码中,带参的宏是简单的作文本替换

相同点:  两个都代码展开,省去了参数压栈、栈帧开辟与回收,结果返回等,从而提高运行速度。

注:

一般写在头文件中
只在release版本生效
给编译器的一个建议,循环、递归、switch一定不会出现inline。
inline基于实现,不是基于声明,即在声明点无效(先声明后内联)

C++基础:inline函数相关推荐

  1. Template 基础篇-函数模板

    ====================================================|| 欢迎讨论技术的可以相互加微信:windgs (请备注csdn+xx职业) ======== ...

  2. fig r函数_R语言基础绘图函数散点图~跟着Nature Communications学画图~Figure1

    今天继续 跟着Nature Communications学画图系列第二篇.学习R语言基础绘图函数画散点图. 对应的 Nature Communications 的论文是 Fecal pollution ...

  3. 关于inline函数

    (一)inline函数(摘自C++ Primer的第三版) 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int ...

  4. python绘图实例-Python matplotlib基础绘图函数示例

    原标题:Python matplotlib基础绘图函数示例 Pyplot基础图标函数: 函数 说明 plt.plot(x,y,fmt,-) 绘制一个坐标图 plt.boxplot(data,notch ...

  5. python的用途实例-Python基础之函数原理与应用实例详解

    本文实例讲述了Python基础之函数原理与应用.分享给大家供大家参考,具体如下: 目标 函数的快速体验 函数的基本使用 函数的参数 函数的返回值 函数的嵌套调用 在模块中定义函数 01. 函数的快速体 ...

  6. C++ inline函数和宏

    1. 内联函数 在C++中我们通常定义以下函数来求两个整数的最大值: int max(int a, int b) {return a > b ? a : b; } 为这么一个小的操作定义一个函数 ...

  7. python中使用函数的优点_Python基础之函数基本用法与进阶详解

    本文实例讲述了Python基础之函数基本用法与进阶.分享给大家供大家参考,具体如下: 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数 ...

  8. TypeScript基础入门 - 函数 - 简介

    2019独角兽企业重金招聘Python工程师标准>>> 转载 TypeScript基础入门 - 函数 - 简介 项目实践仓库 https://github.com/durban89/ ...

  9. inline函数使用容易导致出错的问题

    对于inline函数,首先应该要短小(inline只是对编译器的一个建议,编译器是可以忽略的),其次inline函数的定义一定要与调用它的部分在同一个源文件里,不同的源文件可以分别定义一个相同inli ...

最新文章

  1. 苹果Q1财报出炉:手机收入下滑15%,服务收入增长19%
  2. iOS多线程编程:线程同步总结 NSCondtion
  3. 分布式事务框架 seata-golang 通信模型详解
  4. linux band0 手动重启,linux相关知识整理(4)
  5. 斯坦福NLP组最新报告:自然语言处理中的学习挑战(附149页报告全文下载
  6. spoon无法初始化至少一个步骤_手机怎么设置无线路由器 手机设置无线路由器步骤【详解】...
  7. php+页面加载进度,基于jQuery实现模拟页面加载进度条_jquery
  8. Ubuntu设置开机启动
  9. VB.NET 反射机制取得当前函数名 类名
  10. 对于GetMemory()函数
  11. 大数据到底在用什么姿势塑造我们?
  12. uci2019计算机录取,美国加州大学这九所分校2019最新录取数据
  13. Spring 中 MongDB Conver转换器的使用
  14. 非视距成像:硬件设备总结
  15. JavaScript案例之抽奖机
  16. 商城、门户、微信服务平台、CMS、易企秀、红包、分销商城、游戏源代码
  17. Py之scorecardpy:scorecardpy的简介、安装、使用方法之详细攻略
  18. macOS Catalina 10.15.6(19G2021)原版镜像CDR下载
  19. BetaFlight深入传感设计:传感模块设计框架
  20. 用matlab实现共轭梯度法求解实例,用MATLAB实现共轭梯度法求解实例

热门文章

  1. Ubuntu修改用户名并赋予sudo权限
  2. 安装SQL Server2008和Visual Studio2008 提示:该服务器上安装了以前版本的VS2008
  3. 合格的数据分析师应该掌握哪些技能
  4. 快来!礼物替你选好了:2022年神秘的程序员周历!
  5. Oracle导入dmp文件乱码解决案例
  6. PrintWriter类详解
  7. gulp--解决watching xx.html : watch task has to be a function的问题
  8. $.getJSON( )的使用方法简介
  9. “小白Hare的成长之路“关于java 使用IO流对音频文件进行复制
  10. windows+python+bleak+BLE低功耗蓝牙通讯连接