你了解内联函数吗?

内联函数

概念

inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数能提升程序运行的效率。对比于传统的函数调用,内联函数更像宏。告诉编译器在调用函数时将函数的代码插入到调用处,从而减少函数跳转、维护函数栈帧等操作所花费的时间,但是由于所有调用内联函数处都要将其展开,这样会耗费一定的空间。所以,内联函数实际上是一种用空间换时间的做法。

观察以下代码中的函数调用

9dca33f161134d1cb2c1495cf162086f.png

05ab6001f8c94d45b2ca8a9465016cc1.png

现在我们用inline修饰add函数再观察其函数在底层是如何调用的。

f4fbf490f5df4e388391acf89a9a7875.png

a09b05a4a749437fab20cecd6ff95ba4.png

我们发现,在调用add()时并没有call指令,也就意味着没有函数跳转,进而证实了,用inline装修的函数直接展开计算。

 如何查看到编译器对内联函数的处理呢?

1. 在release模式下,查看编译器生成的汇编代码中是否存在call Add

60e181b0ca354e8d8ed288ea8eadf2fa.png

2. 在debug模式下,需要对编译器进行设置,否则不会展开(因为debug模式下,编译器默认不会对代码进行优化)

步骤:

2eecbcfd4f1e4ff5925db7d4a950b158.png

7050303be2f8402bbabed0a2cdfa3364.png

8c5d7fc7b8f94283a5ba90199cf88b23.png

acf4553332c743d9b0ab4a3df9662a98.png

e57b0456cb6f4b329f6783d876dfa578.png 20a569438f124c0ea7f492b42ef0b25f.png

内联函数特性

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

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

3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址
了,链接就会找不到(只在当前文件内生效).
f9f89ecfc8d742b18024daa238ea24cb.png

920f5a18a3d74c32bb491e2021725317.png

面试题

宏的优缺点:

优点:

1.增强代码的复用性。
2.提高性能
缺点:

1.不方便调试宏。(因为预编译阶段进行了替换)
2.导致代码可读性差,可维护性差,容易误用
3.没有类型安全的检查 。

  C++有哪些技术替代宏?
1. 常量定义 换用const enum
2. 短小函数定义 换用内联函数

inline和宏的使用场景?

内联函数:

使用场景:

  1. 适用于中小规模的函数: 内联函数通常适用于函数体较小的情况,这样可以避免函数调用的开销。
  2. 频繁调用的函数: 内联函数对于频繁调用的函数比较有效,因为避免了函数调用的开销。
  3. 提高性能: 在一些性能敏感的场景中,通过内联函数可以减少函数调用带来的额外开销。

区别:

  1. 类型检查: 内联函数进行了类型检查,而且它是真正的函数,因此具有类型安全性。
  2. 符号表: 内联函数有自己的符号表,可以提供更好的封装和作用域。

宏:

使用场景:

  1. 简单而短小的代码: 宏通常用于定义简单而短小的代码块。
  2. 代码生成: 用于在预处理阶段生成代码,可以通过宏来实现代码的重复或模板化。

区别:

  1. 类型检查: 宏在预处理阶段进行文本替换,没有类型检查可能导致一些不容易察觉的错误。
  2. 作用域:没有自己的作用域,是简单的文本替换,可能导致一些命名冲突或意外的替换。

共同点:

  1. 性能优化: 都是为了提高代码执行效率而设计的工具。
  2. 代码体积增加: 过度使用内联函数或宏都可能导致代码体积增加,对缓存不友好,反而影响性能。

 

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

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

相关文章

C++初阶:适合新手的手撕vector(模拟实现vector)

上次讲了常用的接口:C初阶:容器(Containers)vector常用接口详解 今天就来进行模拟实现啦 文章目录 1.基本结构与文件规划2.空参构造函数(constructor)4.基本函数(size(),capacity(),resize(),reserve())4.增…

软件文档测试

1 文档测试的范围 软件产品由可运行的程序、数据和文档组成。文档是软件的一个重要组成部分。 在软件的整人生命周期中,会用到许多文档,在各个阶段中以文档作为前阶段工作成果的体现和后阶段工作的依据。 软件文档的分类结构图如下图所示: …

fast.ai 深度学习笔记(七)

深度学习 2:第 2 部分第 14 课 原文:medium.com/hiromi_suenaga/deep-learning-2-part-2-lesson-14-e0d23c7a0add 译者:飞龙 协议:CC BY-NC-SA 4.0 来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它,…

InternLM大模型实战-1.书生浦语大模型全链路开源体系

文章目录 前言笔记正文大模型成为热门关键词书生浦语开源历程从模型到应用书生浦语全链条开源开放体系数据预训练微调评测部署部署智能体LagentAgentLego 总结 前言 本系列文章是参与书生浦语全链路开源体系学习的笔记文章。B站视频教程地址: 笔记正文 大模型成为…

【算法训练营】数字盒子,重编码,成绩排序(python实现)

数字盒子 问题描述 你有一个盒子,你可以往里面放数,也可以从里面取出数。 初始时,盒子是空的,你会依次做 Q 个操作,操作分为两类: 插入操作:询问盒子中是否存在数 x,如果不存在则把数…

Java图形化界面编程——菜单组件 笔记

2.7 菜单组件 ​ 前面讲解了如果构建GUI界面,其实就是把一些GUI的组件,按照一定的布局放入到容器中展示就可以了。在实际开发中,除了主界面,还有一类比较重要的内容就是菜单相关组件,可以通过菜单相关组件很方便的使用…

KAJIMA CORPORATION CONTEST 2024(AtCoder Beginner Contest 340)ABCDEF 视频讲解

这场比较郁闷,C题短路,连续4次WA,导致罚时太多 A - Arithmetic Progression Problem Statement Print an arithmetic sequence with first term A A A, last term B B B, and common difference D D D. You are only given inputs for w…

算法学习——LeetCode力扣栈与队列篇2

算法学习——LeetCode力扣栈与队列篇2 150. 逆波兰表达式求值 150. 逆波兰表达式求值 - 力扣(LeetCode) 描述 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。…

《Python 网络爬虫简易速速上手小册》第9章:爬虫项目的部署与运维(2024 最新版)

文章目录 9.1 爬虫的部署策略9.1.1 重点基础知识讲解9.1.2 重点案例:使用 Docker 部署爬虫到云服务平台9.1.3 拓展案例 1:使用 Kubernetes 管理爬虫的部署和扩展9.1.4 拓展案例 2:利用 GitHub Actions 实现 CI/CD 9.2 日志管理与错误处理9.2.…

“深度解析Java虚拟机:运行时数据区域、垃圾收集、内存分配与回收策略、类加载机制“

"深度解析Java虚拟机:运行时数据区域、垃圾收集、内存分配与回收策略、类加载机制" Java 虚拟机一、运行时数据区域程序计数器Java 虚拟机栈本地方法栈堆方法区运行时常量池直接内存 二、垃圾收集判断一个对象是否可被回收1. 引用计数算法2. 可达性分析算…

fast.ai 深度学习笔记(一)

深度学习 2:第 1 部分第 1 课 原文:medium.com/hiromi_suenaga/deep-learning-2-part-1-lesson-1-602f73869197 译者:飞龙 协议:CC BY-NC-SA 4.0 来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它,这…

使用vue-client-only 解决组件不兼容SSR问题

目录 前言 一、解决方案 1.基于Nuxt 框架的SSR应用 2.基于vue2框架的应用 3.基于vue3框架的应用 二、总结 往期回顾 前言 最近在我的单页面SSR应用上开发JSON编辑器功能,在引入组件后直接客户端跳转OK,但是在直接加载服务端渲染的时候一直报这…

解密输入输出迷局:蓝桥杯与ACM中C++/C语言常见问题揭秘

关于C中的常见输入输出汇总 带空格的字符串: ​ 对于这种输入方式我们选择使用gets() 函数来进行输入,gets用于从标准输入(通常是键盘)读取一行文本并将其存储为字符串,直到遇到换行符(‘\n’&#xff09…

javaEE - 22( 5000 字 Tomcat 和 HTTP 协议入门 -3)

一:Tomcat 1.1 Tomcat 是什么 谈到 “汤姆猫”, 大家可能更多想到的是大名鼎鼎的这个: 事实上, Java 世界中的 “汤姆猫” 完全不是一回事, 但是同样大名鼎鼎. Tomcat 是一个 HTTP 服务器. 前面我们已经学习了 HTTP 协议, 知道了 HTTP 协议就是 HTTP 客户端和…

基于FPGA的图像最近邻插值算法verilog实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将FPGA数据导入matlab显示图片,效果如下: 2.算法运行软件版本 vivado2019.2,matlab2022a 3.部分核心程序 ti…

python高校实验室管理系统的django设计与实现81txp

技术栈 后端:python 前端:vue.jselementui 框架:django Python版本:python3.7 数据库:mysql5.7 数据库工具:Navicat 开发软件:PyCharm .本高校实验室管理系统采用python语言、MySQL数据库&…

Flink基础篇|002_Flink前世今生

📫 作者简介:「六月暴雪飞梨花」,专注于研究Java,就职于科技型公司后端工程师 🏆 近期荣誉:华为云云享专家、阿里云专家博主、腾讯云优秀创作者 🔥 三连支持:欢迎 ❤️关注、&#x…

【计算机网络】协议层次及其服务模型

协议栈(protocol stack) 物理层链路层网络层运输层应用层我们自顶向下,所以从应用层开始探究应用层 协议 HTTP 提供了WEB文档的请求和传送SMTP 提供电子邮件报文的传输FTP 提供两个端系统之间的文件传输报文(message)是…

gem5学习(19):gem5内存系统——The gem5 Memory System

目录 一、Model Hierarchy 二、CPU 三、Data Cache Object 四、Tags & Data Block 五、MSHR and Write Buffer Queues 六、Memory Access Ordering 七、Coherent Bus Object 八、Simple Memory Object 九、Message Flow 1、Memory Access Ordering(re…

【MySQL】MySQL表的增删改查(进阶)

MySQL表的增删改查(进阶) 1. 数据库约束1.1 约束类型1.2 NULL约束1.3 UNIQUE:唯一约束1.4 DEFAULT:默认值约束1.5 PRIMARY KEY:主键约束1.6 FOREIGN KEY:外键约束:1.7 CHECK约束(了解) 2. 表的设…