C++修炼之练气期第八层——内联函数
创始人
2025-05-28 13:26:27
0

  

文章目录

一、宏的缺点

引例

改正一

改正二

改正三

宏的缺陷

二、内联函数的概念

三、内联与非内联的区别

四、内联函数的特性


专栏导读

🌸作者简介:花想云,在读本科生一枚,致力于 C/C++、Linux 学习。

🌸本文收录于 C++系列,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新!

🌸相关专栏推荐:C语言初阶系列 C语言进阶系列 数据结构与算法 

大家是否还记得C语言中的宏函数?内联函数与C语言中宏函数作用类似,但是由于宏的缺陷较多,使用体验较差且安全性不高,所以C++中不建议使用宏,而是使用内联函数替代宏。本章我们就一起学习内联函数吧~

一、宏的缺点

引例

在学习宏时,我们曾经实现过ADD的宏函数,作用是求两个数的和。例如:

#define ADD(x , y)  x+y;

如果你的宏学的还不错的话,会发现上面的代码就是个典型的错误示例,说是错误锦集也不为过。我们试着将它修改正确。

改正一

首先,末尾的分号是必须要去掉的,否则编译都不会通过;

//改正一
#define ADD(x , y)  x+y

好了,接下来进行测试;

//测试用例1
int a = 3, b = 5;
printf("%d\n", ADD(a, b));//测试用例2
printf("%d\n", ADD(a | b, a & b);

执行结果为:测试用例1通过、测试用例2错误;

原因是 #define 意为替换,测试用例实际上执行的是:

printf("%d\n", 3 | 5 + 3 & 5);

又因为运算符 ' + ' 的优先级高于 ' & ' 和 ' | ' ,所以结果错误。

那么继续改正。

改正二

为了解决优先级问题,需要给每个值都添加括号;

#define ADD(x , y)  (x)+(y)

继续测试;

//测试用例3
int a = 3, b = 5;
printf("%d\n", ADD(a, b)*2);

OK,测试未通过,原因很简单:乘优先于加;编译后的代码其实是这样的:

printf("%d\n", (3)+(5)*2);

继续改正;

改正三

依然是优先级的问题,这次需要为整体添加括号;

#define ADD(x , y)  ((x)+(y))

终于,我们的ADD宏函数最终被修改正确。

宏的缺陷

显而易见,一个功能如此简单的ADD宏,都有这么多错误的版本,要是面对复杂的工程项目那么宏的安全性就让它的使用变得谨慎万分。

此外,宏的缺点还有:

1. 宏不能调试;

由于宏在预处理阶段就会被替换,所以不能调试。

2. 宏没有类型检查;

宏的参数不需要定义类型,导致宏容易出现类型相关的错误。

3. 有些场景下非常复杂,容易出错,不容易掌握。

二、内联函数的概念

用 inline 修饰的函数叫做 内联函数,类似于宏,编译阶段内联函数在调用的地方进行展开,不会建立函数栈帧。没有了建立函数栈帧的开销,意味着程序的效率会因此提高。

//定义一个内联函数
inline int Add(int x, int y)
{return x + y;
}int main()
{int a = 3, b = 5;int ret = Add(a, b);cout << ret << endl;return 0;
}

三、内联与非内联的区别

非内联函数在调用时,会建立函数栈帧,内联函数则不会;下面我们就在调用两种不同的函数时,查看各自的汇编代码。

//非内联函数
int Add(int x, int y)
{return x + y;
}int main()
{int a = 3, b = 5;int ret = Add(a, b);cout << ret << endl;return 0;
}


如上图所示,该指令就是调用函数的指令,调用函数必会建立函数栈帧。再来看看内联函数;

//内联函数
inline int Add(int x, int y)
{return x + y;
}int main()
{int a = 3, b = 5;int ret = Add(a, b);cout << ret << endl;return 0;
}

如图,此处并没有调用函数的过程,而是直接展开。

四、内联函数的特性

内联函数并不总是最好的选择,它也是有利有弊。

1. inline 是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。

2. inline 对于编译器而言只是一个建议,不同编译器关于 inline 实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用 inline 修饰,否则编译器会忽略 inline 特性。

例如,我们将上述内联函数Add稍作修改,使它看起来规模较大较为繁琐,此时内联函数特性被忽略。

inline int Add(int x, int y)
{int z = x + y;z = x + y;z += x + y;z = x + y;z = x + y;z = x * y;z = x + y;z += x + y;z -= x + y;z += x + y;z += x * y;z -= x / y;z += x + y;z += x + y;return z;
}

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

相关内容

热门资讯

毕业典礼园长优秀致辞 毕业典礼园长优秀致辞(精选5篇)  在平凡的学习、工作、生活中,大家都不可避免地会接触到致辞吧,致辞...
辞职报告表格2份   员工辞职报告表格一  填写日期: 2010 年 月 日 ...
最近很火的辞职书 最近很火的辞职书(精选20篇)  在某个公司奋斗时间长了,总会有一些因素让我们选择辞职,那么不要忘了...
简单辞职信 简单辞职信范文(精选15篇)  工作中,有人入职,自然有人辞职,我们可能会因为某些原因离开职位,为此...
医院辞职报告 医院辞职报告医院辞职报告敬爱的院领导:由于我个人身体的原因,经过深思熟虑地考虑,决定辞去目前在我院的...
公司销售员辞职报告 公司销售员辞职报告  当我们在岗位上体验过一段时间后,我们可能会觉得自己并不适合现有工作岗位,为了避...
公司周年庆总经理致辞 公司周年庆总经理致辞范文  在生活、工作和学习中,大家都用到过致辞吧,在各种重大的庆典、外交、纪念活...
婚礼父亲致辞简短大气男方 婚礼父亲致辞简短大气男方(通用10篇)  在日常的学习、工作、生活中,许多人都有过写致辞的经历,对致...
文化旅游节开幕式致辞 文化旅游节开幕式致辞范文(精选7篇)  在学习、工作、生活中,要用到致辞的地方还是很多的,致辞具有针...
宾馆辞职报告 宾馆辞职报告  现今,辞职越来越常见了,即使工作很好,因为想看看外面的世界,我们可能会选择辞职,这种...
运动员致辞 运动员致辞范文三篇  导语:运动员一词,起源于古希腊文“裸体”的意思。从古希腊的雕刻上,我们还可以看...
企业发展规划书(2) 企业发展规划书范文  1. 内部收益率 40%, 投资回收期2年。  2.以××××学院出面融资(也...
房地产辞职报告 房地产辞职报告15篇  在我们平凡的日常里,报告对我们来说并不陌生,报告具有语言陈述性的特点。一听到...
职业生涯规划引言 前言:我们对自己进行了职业生涯规划设计,就是给自己的梦想插上翅膀。远大的理想总是建立在坚实的土地上的...
大学生职业生涯规划设计书   2017大学生职业生涯规划设计书一  今天,如果你不生活在未来,那么,明天你将生活在过去!  年...
大学职业规划书大一新生 大学职业规划书大一新生  大学大一新生职业规划书(精选15篇)  时间就如同白驹过隙般的流逝,我们又...
七年级地理教学计划 七年级地理教学计划  日子如同白驹过隙,不经意间,老师们的教学工作又将有新的目标,现在就让我们好好地...
会计职业规划的职业规划 会计职业规划的职业规划(通用9篇)  东流逝水,叶落纷纷,荏苒的时光就这样悄悄地,慢慢地消逝了,我们...
商务内贸的工作思路 商务内贸的工作思路  一、紧贴“三化”建设要求,创新内贸工作思路。  1、培育好新型建材行业的发展。...
学业水平提升计划 学业水平提升计划(精选13篇)  日子如同白驹过隙,又将迎来新的工作,新的挑战,现在就让我们好好地规...