什么是 C++ 内联函数?它的作用是什么?内联函数与普通函数有什么区别?如何定义和使用内联函数?

1) 什么是 C++ 内联函数?它的作用是什么?

在C++中,内联函数是一种特殊的函数,它在编译时会将函数体直接嵌入到调用该函数的地方,而不是像普通函数那样进行函数调用的开销。以下是关于内联函数的详细介绍:

定义方式

内联函数使用关键字 inline 来定义,通常的定义形式如下:

inline 返回类型 函数名(参数列表) {// 函数体
}
作用
  • 提高程序运行效率:对于一些函数体较小、执行频繁的函数,使用内联函数可以避免函数调用时的压栈、出栈等开销,从而提高程序的运行速度。因为在编译期间,编译器会直接将内联函数的代码插入到调用该函数的地方,就好像把函数体中的代码直接写在调用处一样,减少了函数调用的时间成本。
  • 增强代码的可读性:内联函数可以像普通函数一样进行封装和命名,使代码的逻辑结构更加清晰,易于理解和维护。通过将一段具有特定功能的代码封装成内联函数,可以提高代码的可读性和可维护性,同时又能在需要的地方方便地调用,而不必重复编写相同的代码。
适用场景

短小且频繁调用的函数:例如,一些简单的数学运算函数、访问器函数等,它们的函数体通常比较短小,但在程序中可能会被频繁调用。将这些函数定义为内联函数,可以有效地提高程序的性能。

inline int add(int a, int b) {return a + b;
}

对性能要求较高的关键代码段:在一些对性能要求极为苛刻的程序中,如实时控制系统、高频交易系统等,对于那些对性能有较大影响的函数,可以考虑将其定义为内联函数,以尽可能地减少运行时间。

注意事项
  • 代码膨胀:过度使用内联函数可能会导致代码膨胀,因为内联函数的代码会在每个调用处都被展开,这可能会增加可执行文件的大小。特别是对于一些函数体较大的函数,如果将其定义为内联函数,可能会导致生成的代码量大幅增加,从而影响程序的性能和可维护性。
  • 编译时间增加:由于内联函数需要在编译期间进行展开,这可能会增加编译的时间。尤其是当内联函数较多且函数体较复杂时,编译时间可能会显著增加。
  • 递归函数和虚函数不适合内联:递归函数由于其自身的调用特性,无法直接在编译时确定展开的深度和次数,因此不适合定义为内联函数。虚函数是通过动态绑定来实现多态性的,其调用的具体函数在运行时才能确定,而内联函数是在编译时进行展开的,所以虚函数也不能被定义为内联函数。

2) 内联函数与普通函数有什么区别?如何定义和使用内联函数? 

内联函数和普通函数在多个方面存在区别,以下是详细介绍:

定义方式

普通函数:按照常规的函数定义语法进行定义,例如:

返回类型 函数名(参数列表) {// 函数体
}

内联函数:在函数定义前加上关键字 `inline`,形式如下:

inline 返回类型 内联函数名(参数列表) {// 函数体
}
调用方式
  • 普通函数:在程序中通过函数名和参数列表进行调用,程序执行到函数调用语句时,会跳转到函数的定义处执行函数体中的代码,执行完毕后再返回到调用点继续执行后续代码。
  • 内联函数:在编译阶段,编译器会将内联函数的代码直接嵌入到调用该函数的地方,就好像直接把函数体中的代码写在调用处一样,而不是像普通函数那样进行跳转和返回的操作。
执行效率
  • 普通函数:每次调用普通函数时,都需要进行一系列的操作,如保存当前函数的上下文、将参数压栈、跳转到函数的入口地址、执行函数体中的代码、恢复调用函数的上下文等,这些操作会带来一定的时间开销,尤其是对于函数体较小但调用频繁的函数,这种开销可能会比较明显。
  • 内联函数:由于内联函数在编译时将函数体直接嵌入到调用处,避免了函数调用的额外开销,因此在函数体较小且调用频繁的情况下,可以显著提高程序的执行效率。
代码展开
  • 普通函数:函数的代码在内存中只有一份,无论在程序的多少个地方调用该函数,都是跳转到同一个函数地址去执行相同的代码。
  • 内联函数:在每个调用内联函数的地方,编译器都会将内联函数的完整代码展开插入,这可能会导致代码体积增大,但对于一些对性能要求较高且函数体较小的情况,这种代码展开带来的性能提升是值得的。
适用场景
  • 普通函数:适用于函数体较大、功能复杂、不需要频繁调用的函数,或者函数的实现可能会经常发生变化的情况。
  • 内联函数:适合函数体较小、执行频繁的函数,如一些简单的数学运算函数、访问器函数等,将它们定义为内联函数可以减少函数调用的开销,提高程序的运行速度。
注意事项
  • 普通函数:普通函数的定义和实现可以分开在不同的文件中,通过头文件进行声明和调用,便于代码的组织和管理。
  • 内联函数:内联函数通常建议将定义放在头文件中,因为编译器在编译每个使用内联函数的源文件时都需要知道内联函数的完整定义以便进行代码展开。如果将内联函数的定义放在源文件中,而在其他源文件中调用该内联函数,可能会导致链接错误。

以下是一个内联函数的定义和使用示例:

// 定义内联函数
inline int add(int a, int b) {return a + b;
}int main() {int num1 = 5, num2 = 3;// 使用内联函数int result = add(num1, num2);return 0;
}

在上述示例中,add 函数被定义为内联函数,在 main 函数中调用 add 函数时,编译器会将 add 函数的代码直接展开到调用处,从而提高了代码的执行效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18343.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

二叉树的层序遍历

一、题目 给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历) 例如: 给定的二叉树是{3,9,20,null,null,15,7}, 该二叉树层序遍历的结果是 [[3],[9,20],[15,7]] 二、解决方案 2.0 树…

模型训练过程的显存占用实测

依赖项说明 pip install nvitop pip install timm pip install peft后续的显存占用数据截图,均基于nvitop命令实现 1、模型显存占用说明 1.1 理论占用值 在 一文讲明白大模型显存占用(只考虑单卡)与大模型显存占用分析都对模型训练过程中…

后端分层解耦

引入 在上篇所举的例子中,我们将所有的代码均放在HelloControl方法之中,这样会导致代码的复用性、可读性较差,难以维护。因此我们需 三层架构 在之前的代码中,代码大体可以分为三部分:数据访问、数据逻辑处理、响应数…

AIGC 入门全攻略:开启智能创作新时代

一、AIGC 初印象 AIGC,即人工智能生成内容,是继专业生产内容(PGC)、用户生产内容(UGC)之后的新型内容创作方式。它涵盖了文本生成、图像与视频创作、音频生成等多个领域,正在以惊人的速度改变着…

约克VRF地暖中央空调,让你舒适过冬

想要冬季过得舒服,采暖必须要到位!对于没有集中供暖的南方地区来说,冬季室内阴冷刺骨。 选购地暖中央空调时,强效制热的能力必不可少,让我们可以享受温暖的室内温度,有效减少室内忽冷忽热的温度变化。 约克…

基于Java Springboot宠物领养救助平台

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…

使用原生 OpenTelemetry 解锁各种可能性:优先考虑可靠性,而不是专有限制

作者:来自 Elastic Bahubali Shetti•Miguel Luna Elastic 现在支持使用 OTel Operator 在 Kubernetes 上部署和管理 Elastic Distributions of OpenTelemetry (EDOT)。SRE 现在可以访问开箱即用的配置和仪表板,这些配置和仪表板旨在通过 Elastic Observ…

基于python Django的boss直聘数据采集与分析预测系统,爬虫可以在线采集,实时动态显示爬取数据,预测基于技能匹配的预测模型

本系统是基于Python Django框架构建的“Boss直聘”数据采集与分析预测系统,旨在通过技能匹配的方式对招聘信息进行分析与预测,帮助求职者根据自身技能找到最合适的职位,同时为招聘方提供更精准的候选人推荐。系统的核心预测模型基于职位需求技…

安装 python-pcl 遇到的问题

安装python-pcl 成功安装错误尝试尝试一尝试二尝试三 本人环境 Ubuntu 22.04.4LTS ros2-humble cpython 3.0.11 python 3.10.12 libpcl-dev 1.12.1dfsg-3build1 pcl-tools 1.12.1dfsg-3build1 代码摘抄来源:Breadcrumbsouster-ros-extras/scripts/ros2_pcl_filters.…

【C++进阶篇】——string类的使用

文章目录 前言:1. string的介绍2. string类对象的常见构造3. string类对象的容量操作4. string类对象的访问5. 迭代器6. string类对象的修改操作7. string类对象的字符串运算8.string类成员函数9.string类非成员函数10.string类常量成员 前言: std::str…

vmware虚拟机给创建的centos扩展磁盘步骤

1.先看看原来的磁盘信息,目前磁盘是20g的,重点关注红色箭头指向的地方,一个17g 可用11g,接下来要对其进行扩展 df -h2.关闭当前虚拟机,先进行磁盘扩展,目前我扩展到了50g。 3.重新开启虚拟机,…

开源物业管理系统助力智能社区提升服务效率与用户体验

内容概要 开源物业管理系统是一种灵活、智能的解决方案,专为社区物业管理而生。随着智能社区的发展,这种系统变得越来越重要。它不仅帮助物业管理者高效地处理日常事务,还提升了居民的生活体验。在这个日新月异的时代,开源物业管…

深入理解 Redis跳跃表 Skip List 原理|图解查询、插入

1. 简介 跳跃表 ( skip list ) 是一种有序数据结构,通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。 在 Redis 中,跳跃表是有序集合键的底层实现之一,那么这篇文章我们就来讲讲跳跃表的实现原理。 2. …

【数据库】mysql数据库迁移前应如何备份数据?

MySQL 数据库的备份是确保数据安全的重要措施之一。在进行数据库迁移之前,备份现有数据可以防止数据丢失或损坏。以下是一套详细的 MySQL 数据库备份步骤,适用于大多数情况。请注意,具体的命令和工具可能因 MySQL 版本的不同而有所差异。整个…

AWTK-WIDGET-WEB-VIEW 实现笔记 (4) - Ubuntu

Ubuntu 上实现 AWTK-WIDGET-WEB-VIEW 开始以为很简单,后来发现是最麻烦的。因为 Ubuntu 上的 webview 库是 基于 GTK 的,而 AWTK 是基于 X11 的,两者的窗口系统不同,所以期间踩了几个大坑。 1. 编译 AWTK 在使用 Linux 的输入法时…

Rocket入门练习

搭建部署: 1. 部署平台和部署方式: Ubuntu:22.10 部署方式:源码安装部署 a. 下载源码到本地:rocketmq-all-5.3.1-source-release.zip $ unzip rocketmq-all-5.3.1-source-release.zip // 解压缩 $ cd rocketmq-all…

视觉SLAM相机——单目相机、双目相机、深度相机

一、单目相机 只使用一个摄像头进行SLAM的做法称为单目SLAM,这种传感器的结构特别简单,成本特别低,单目相机的数据:照片。照片本质上是拍摄某个场景在相机的成像平面上留下的一个投影。它以二维的形式记录了三维的世界。这个过程中…

EM算法与高斯混合聚类:理解与实践

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…

悬浮窗,ViewPager2内嵌套RecyclerView,RecyclerView高度异常的问题分析

1 背景 在一个Adnroid项目中,使用到了悬浮窗,其中有一个需求是以分页的显示显示媒体item,每一页中展示的媒体item是一个网格列表的形式显示的。 原型图如下: 2 实现方案 上述需求实现分页采用ViewPager2,在xml中的…

wordpress使用相关

这里写目录标题 遇到的相关问题WordPress安装插件过程中遇到需要ftp出现确实XMLReader 插件的提示cURL Support Missing(curl 缺失) 遇到的相关问题 WordPress安装插件过程中遇到需要ftp 一般在这个位置 出现确实XMLReader 插件的提示 解决&#xff1a…