C++特性——inline内联函数
1. 内联函数
1.1 C语言的宏
在C语言中,我们学习了用#define定义的宏函数,例如:
#define Add(x, y) ((x) + (y)) //两数相加
相较于函数,我们知道宏替换具有如下比较明显的优点:
- 性能优势: 宏在预处理阶段进行简单的文本替换,没有函数调用的开销,可以节省栈空间
- 灵活的参数: 宏的参数可以是任意表达式,包括副作用表达式。这使得宏能够以更灵活的方式进行代码替换,可以处理一些复杂的操作。
但是,对应的C语言的宏替换也有这些致命的缺陷:
- 不进行类型检查: 宏在进行文本替换时不进行类型检查,这可能导致一些潜在的类型错误。
- 没有作用域: 宏在预处理阶段进行文本替换,没有作用域的概念。如果宏的名称与其他标识符冲突,可能会导致错误或意外行为
- 不可随意调试: 在调试过程中,很难对宏展开后的代码进行单步调试,因为宏展开发生在预处理阶段,调试器无法直接查看宏的展开结果。
注:如果想对C语言的宏有更深的了解,建议看看👉C语言——预处理
1.2 内联函数
而为了解决C语言#define宏所带来的缺陷,C++有了inline关键字。
- 我们在函数的返回值类型前面加入
inline关键字,这个函数就成为了内联函数。 - 内联函数会在编译时被展开,从而避免了栈帧开销。
- 同时,内联函数又具有函数的特性。因此具有类型检查、作用域且方便调试。相较于宏函数更加安全。
- 可以说内联函数在具有宏函数优点同时也完全解决了宏函数所带来的缺陷。
例如:
inline void Func()
{printf("Hello World\n");
}int main()
{for (int i = 0; i < 100; i++)Func();return 0;
}
上面的代码我们声明了一个内联函数Func,在编译过后循环处的调用就会变成:
for (int i = 0; i < 100; i++)printf("Hello World\n"); //内联函数Func直接被展开成了函数体内的内容
1.2.1 通过反汇编查看内联函数的展开
以VS2019为例:
首先,要用反汇编查看内联函数的展开,首先要对编译器做如下设置:
-
首先,将
Debug模式改为Release模式
-
然后,右击项目名称,点击属性

-
接着,配置属性-> C/C++ -> 常规 -> 调试信息格式 ->程序数据库

- 最后,配置属性-> C/C++ -> 优化 -> 内联函数扩展 -> 只适用于
_inline

设置完成过后,我们就可以通过返汇编查看内联函数的展开了。
-
我们先来看看没有加入
inline关键字的普通函数:
-
再来看看加入
inline关键字的内联函数:
1.2.2 内联函数的局限性
既然内联函数可以避免栈帧开销而且安全性也有保证,那是不是可以说以后我们可以将所有的函数都定义成内联函数呢?
当然不可以!!!
首先我们来看一组对比:

- 可以发现,不是内联函数的文件空间比是内联函数的文件空间小了16KB
- 有小伙伴就会问了:不就十几KB嘛,磁盘空间这么大不差这点。但是如果我将一个几百行的函数也写成一个内联函数,那这二者之间占用空间的差距就不会这么小了。
所以我们有必要清楚内联函数的局限,知道什么时候可以用,什么时候不可以用;
- 通过上面的分析和比较可以知道,
inline内联函数实际上是一种空间换时间的做法:通过代码的展开来减少函数调用的开销,但也因此导致了代码膨胀的问题。 - 因此内联函数一般用作代码简短(不超过10行),经常使用的函数。
- 而对于递归函数、存在大量循环的函数、存在
switch case语句的函数,一般不用inline处理
1.2.3 内联函数的特性
如果有人不听劝,将一个递归函数定义成内联函数,会出现什么情况呢?

- 特性1:inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,如果被定义的函数较为复杂,编译器会
忽略inline特性。 - 特性2:内联函数的声明和定义最好不要分离,否则就只能在定义内联函数的文件中使用该内联函数
1.3 总结
inline内联函数是C++专门针对C语言宏函数的缺陷而设计的。- 其既具有宏函数没有函数调用开销,所耗时间少的优点;同时也基本上解决了宏函数不安全、难以调试的缺点。其功能不可谓不强。
- 然而内联函数也有较大的局限性:其只适用于代码简单、且频繁调用的函数。而对于递归、有大量循环的函数则不适用。
- 内联函数只是对编译器的一个建议,到底才不采用取决于编译器。
- 内联函数的声明和定义最好放在一起。
相关文章:
C++特性——inline内联函数
1. 内联函数 1.1 C语言的宏 在C语言中,我们学习了用#define定义的宏函数,例如: #define Add(x, y) ((x) (y)) //两数相加相较于函数,我们知道宏替换具有如下比较明显的优点: 性能优势: 宏在预处理阶段…...
pensieve运行的经验
1运行run_videopy时出现如下问题: cmd: Union[List[str], str], ^ SyntaxError: invalid syntax原因是EasyProcess版本与python版本不对应,解决办法可见之前这篇博客:SyntaxError: invalid syntax。 2解决完上述问题后,输…...
Qt实现一个电子相册
一、要实现的功能 在窗口中可以显示图片,并且能够通过两个按钮进行图片的前进和后退的顺序切换。有一个按钮,通过这个按钮可以从所存图片资源中随机选取一个图片进行展示通过按钮可以控制图片自动轮播顺序切换的开始与停止,显示当前系统的时…...
R语言:因子分析 factor analysis
文章目录 因子分析数据集处理步骤主成分法做因子分析最大似然法做因子分析因子分析 因子分析的用途与主成分分析类似,它也是一种降维方法。由于因子往往比主成分更易得到解释,故因子分析比主成分分析更容易成功,从而有更广泛的应用。 从方法上来说,因子分析比主成分分析更为…...
SOFAStack软件供应链安全产品解析——SCA软件成分分析
近年来,软件供应链安全相关攻击事件呈快速增长态势,造成的危害也越来越严重,为了保障软件供应链安全,各行业主管单位也出台了诸多政策及技术标准。基于内部多年的实践,蚂蚁数科金融级云原生PaaS平台SOFAStack发布完整的…...
vue中ElementUi的el-table表格绑定行点击事件
<el-table v-loading"loading" :data"messagesList" row-click"goToMassage">handleRowClick(row, event, column) {// 在这里处理行点击事件console.log(行点击事件:, row, event, column);}...
力扣:盛最多水的容器
题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容器。 …...
3D双目跟踪瞳孔识别
人眼数据集通常用于眼部相关的计算机视觉、眼动追踪、瞳孔检测、情感识别以及生物特征识别等领域的研究和开发。以下是一些常见的人眼数据集: BioID Face Database: 这个数据库包含1,521张近距离的人脸图像,其中包括瞳孔位置的标记。它通常用于瞳孔检测和…...
【java】Java项目从开发到部署生产完整流程梳理
文章目录 前言一、开发环境二、项目搭建2.1 Maven创建项目2.1.1 创建maven项目2.1.2 引入依赖2.1.3 maven常用命令 三、SpringBoot基础配置四、项目打包4.1 打包jar4.2 打包war4.2.1 修改项目打包为war包4.2.2 排除内嵌的tomcat,引入外部tomcat4.2.3 添加servlet-ap…...
Casbin实战经验大揭秘:教育培训领域的创新实践和高效优化策略
策略描述语言(论文) 摘要: 为了保护云资源的安全,防止数据泄露和非授权访问,必须对云平台的资源访问实施访问控制。然而,目前主流云平台通常采用自己的安全策略语言和访问控制机制,从而造成两个问题&#x…...
MyBatis篇---第一篇
系列文章目录 文章目录 系列文章目录一、什么是MyBatis二、说说MyBatis的优点和缺点三、#{}和${}的区别是什么?一、什么是MyBatis (1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、…...
三级分类部分三级目录无法加载,后端接口能在前端返回所有数据
目录 项目场景:三类分类部分不显示问题描述:数据库序号128后的目录不显示原因分析: 数据库&JAVA后端代码:后端接口 解决方案:1 数据库序号问题2 JAVA层面1 递归改成非递归写法2重新写接口: 查询cat_id为…...
Leetcode1839. 所有元音按顺序排布的最长子字符串
Every day a Leetcode 题目来源:1839. 所有元音按顺序排布的最长子字符串 解法1:滑动窗口 要找的是最长美丽子字符串的长度,我们可以用滑动窗口解决。 设窗口内的子字符串为 window,每当 word[right] > window.back() 时&…...
C/C++程序设计和预处理
个人主页:仍有未知等待探索_C语言疑难,数据结构,小项目-CSDN博客 专题分栏:C语言疑难_仍有未知等待探索的博客-CSDN博客 目录 一、引言 二、程序的翻译环境和执行环境 1、什么是程序 2、程序的翻译环境 3、程序的执行环境 三、预处理 1、预定义符…...
openssl生成自签名证书
原网址:https://blog.csdn.net/weixin_41767181/article/details/121531007 windows下安装openssl后,生成自签名证书并打包为P12文件的命令如下: 需要注意的是: 每一级的证书中,证书的公司名称等尽量不要一样根证书…...
JAVA毕业设计100—基于Java+Springboot+Vue的WMS仓库管理系统+移动端微信小程序(源码+数据库+部署视频)
基于JavaSpringbootVue的WMS仓库管理系统移动端(源码数据库部署视频) 一、系统介绍 本系统前后端分离带小程序 本系统分为管理员、用户角色(角色权限可自行分配) 功能列表: 1、 数据管理:物料数据管理、物料Bom管理、物料组管理、物料分类管理、供应…...
深度学习推荐系统架构、Sparrow RecSys项目及深度学习基础知识
文章目录 🌟 技术架构:深度学习推荐系统的经典技术架构长啥样?🍊 一、深度学习推荐系统的技术架构🍊 二、基于用户行为的推荐🍊 三、基于多模态数据的推荐🍊 四、基于知识图谱的推荐 dz…...
ios UI 基础开发二
第一节:UIPickerView、UIPickerViewDataSource、UIPickerViewDelegate 设置约束,如果要设置两个兄弟的约束,可以按住option键,用鼠标右键把a拖到b上面,表示a按照b来对齐 生成随机数 如果后面列的数据,依赖前…...
失配树学习笔记
失配树,是一种奇妙的数据结构,它利用 KMP、LCA 解决求两前缀的最长公共 Border 的问题。 首先介绍一下什么是 Border,我们知道 nxt 数组是前后缀相同的最大长度,Border 相当于是 nxt 数组的弱化版,只是去掉了“最大”…...
【Electron】Not allowed to load local resource
问题描述 使用 audio 标签播放音频文件,控制台报错 Not allowed to load local resource。 Not allowed to load local resource原因分析 通常是安全策略所引起的。Electron 默认情况下禁止加载本地资源,以防止潜在的安全风险。 解决方案 在 main.js…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
