【C++函数探幽】内联函数inline
📙 作者简介 :RO-BERRY
📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持

目录
- 1. 前言
- 2.概念
- 3.特性
- 4.内联与宏
1. 前言
内联函数是C++为提高程序运行速度所做的一项改进。常规函数和内联函数之间的主要区别不在于编写方式,而在于C++编译器如何将他们组合到程序中。要了解内联函数与常规函数之间的区别, 必须深入到程序内部。
编译过程的最终产品是可执行程序——由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。有时(如有循环或分支语句时),将跳过一些指令,向前或向后跳到特定地址。常规函数调用也使程序跳到另一个地址(函数的地址),并在函数结束时返回。执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈(为此保留的内存块),跳到标记函数起点的内存单元,执行函数代码(也许还需将返回值放入到寄存器中),然后跳回到地址被保存的指令处(这与阅读文章时停下来看脚注,并在阅读完脚注后返回到以前阅读的地方类似)。来回跳跃并记录跳跃位置意味着以前使用函数时,需要一定的开销。
C++内联函数提供了另一种选择。内联函数的编译代码与其他程序代码“内联”起来了。也就是说,编译器将使用相应的函数代码替换函数调用。对于内联代码,程序无需跳到另一个位置处执行代码,再跳回来。因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存。如果程序在10个不同的地方调用同一个内联函数,则该程序将包含该函数代码的10个副本(参见下图)。

应有选择地使用内联函数。如果执行函数代码的时间比处理函数调用机制的时间长,则节省的时间将只占整个过程的很小一部分。如果代码执行时间很短,则内联调用就可以节省非内联调用使用的大部分时间。另一方面,由于这个过程相当快,因此尽管节省了该过程的大部分时间,但节省的时间绝对值并不大,除非该函数经常被调用。
2.概念
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调
用建立栈帧的开销,内联函数提升程序运行的效率。
查看方式:
- 在release模式下,查看编译器生成的汇编代码中是否存在call Add
- 在debug模式下,需要对编译器进行设置,否则不会展开(因为debug模式下,编译器默认不
会对代码进行优化,以下给出vs2013的设置方式)



3.特性
inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会
用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运
行效率。- inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建
议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不
是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性 - inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址
了,链接就会找不到
要使用这些特性,必须采取以下几个措施之一:
- 在函数声明前加上关键字inline
- 在函数定义前加上关键字inline
通常的做法是省略原型,将整个定义(即函数头和所有函数代码)放在本应该提供原型的地方
4.内联与宏
inline 工具是C++新增的特性。C语言使用预处理器语句#define来提供宏——内联代码的原始实现。例如,下面是一个计算平方的宏:
#define square(x) x*x
这并不是通过传递参数实现的,而是通过文本替换来实现的——X是“参数”的符号标记。
a = square(5.0) ---> a = 5.0 * 5.0
b = square(4.5+7.5) ---> b = 4.5 + 7.5 * 4.5 + 7.5
c = square(s++) ---> c = s++ * s++
上述例子只有一个能正常运行,其他的均达不到我们想要的目的,但是可以通过打括号来进行改进
但很容易出现类似的问题。即宏不能按值传递。
宏的优点:
1.增强代码的复用性。
2.提高性能。
缺点:
1.不方便调试宏。(因为预编译阶段进行了替换)
2.导致代码可读性差,可维护性差,容易误用。
3.没有类型安全的检查 。
内联是传递表达式,所以不会出现使用宏所导致的错误
通过对比可以看到,内联功能是远远超过宏定义的,我们在学习中要多去将以前使用宏定义的地方多去考虑使用内联函数
相关文章:
【C++函数探幽】内联函数inline
📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 目录 1. 前言2.概念3.特性…...
C#面:什么是Code-Behind技术
Code-Behind技术是一种在Web开发中常用的技术,它将前端页面与后端代码分离,使得前端页面的设计和后端代码的逻辑处理可以分别进行。在Code-Behind模式下,前端页面通常是一个标记语言(如HTML或ASPX),而后端代…...
【ES6】Promise
Promise 回调地狱 const fs require(fs);fs.readFile(./a.txt, utf-8, (err, data) > {if(err) throw err;console.log(data);fs.readFile(./b.txt, utf-8, (err, data) > {if(err) throw err;console.log(data);fs.readFile(./c.txt, utf-8, (err, data) > {if(er…...
Leetcode 3035. Maximum Palindromes After Operations
Leetcode 3035. Maximum Palindromes After Operations 1. 解题思路2. 代码实现 题目链接:3035. Maximum Palindromes After Operations 1. 解题思路 这一题的话因为可以任意交换,因此事实上要考察回文的最大个数,我们只需要统计所有单词当…...
SCM供应链系统:一文读懂,需要优化升级的看过来。
单一的供应链系统平时很少碰到,但是很多B端系统中都会集成供应链的功能,贝格前端工场尝试对SCM做一下扫盲性的介绍,如有管理系统界面是优化和升级的需求,欢迎私信我们,共同探讨。 一、定义与由来 SCM有时也可以指供应…...
WSL外部SSH连接有效方法
前言 wsl作为windows下使用linux平台有效的手段之一,本文可以让win作为工作站,外部系统用来连接win下的wsl系统。 自动启动服务脚本 https://zhuanlan.zhihu.com/p/47733615 开机自启端口转发 wslname "Ubuntu-20.04" 要转发端口的Linux…...
MATLAB 1:基础知识
MATLAB中的数据类型主要包括数值类型、逻辑类型、字符串、函数句柄、结构体和单元数组类型。这六种基本的数据类型都是按照数组形式存储和操作的。 MATLAB中还有两种用于高级交叉编程的数据类型,分别是用户自定义的面向对象的用户类类型和Java类类型。 1.1.1数值类…...
django安装使用
Django 是一个高级的 Python Web 框架,用于构建安全和可维护的网站。以下是如何安装和使用 Django 的步骤。 一:安装 确保你安装了 Python 在 Django 3.x 中,官方支持 Python 3.6, 3.7, 3.8, 3.9, 和 3.10。你可以使用 python --version 或…...
基于LightGBM的回归任务案例
在本文中,我们将学习先进的机器学习模型之一:Lightgbm。在对XGB模型进行了越来越多的改进以获得更好的性能之后,XGBoost是一种极限梯度提升机器,但通过lightgbm,我们可以在没有太多计算的情况下实现类似或更好的结果&a…...
CTFshow web(php文件上传155-158)
web155 老样子,还是那个后端检测。 知识点: auto_append_file 是 PHP 配置选项之一,在 PHP 脚本执行结束后自动追加执行指定的文件。 当 auto_append_file 配置被设置为一个文件路径时,PHP 将在执行完脚本文件的所有代码后&…...
Leetcode 53 最大子数组和
题意理解: 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 所以每个元素都有两个状态,是前一部分的延续࿰…...
【pandas 不同文件读取和存储】
文章目录 一、Pandas 文件读取和存储概览二、读取不同类型的文件1. CSV文件的读取与存储代码及解释: 2. Excel文件的读取与存储代码及解释: 3. JSON文件的读取与存储代码及解释: 4. SQL数据库的读取与存储代码及解释: 5. 其他格式…...
python从入门到精通(十六):python爬虫的BeautifulSoup4
python爬虫的BeautifulSoup4 BeautifulSoup4导入模块解析文件创建对象python解析器beautifulsoup对象的种类Tag获取整个标签获取标签里的属性和属性值Navigablestring 获取标签里的内容BeautifulSoup获取整个文档Comment输出的内容不包含注释符号BeautifulSoup文档遍历Beautifu…...
Codeforces Round 924(Div.2) A~E
A.Rectangle Cutting (模拟) 题意: 给出一个长方形,通过平行于原始矩形的一条边进行切割,将该矩形切割成两个边长为整数的矩形。询问是否能通过旋转和移动这两个矩形,得到新的矩形。 分析: 可以发现拼成的新长方形…...
django中实现观察者模式
在Django中实现观察者模式,你可以利用Django的信号(Signals)系统。Django的信号提供了一种发布/订阅模型,允许解耦应用程序组件之间的交互。一个组件可以发送一个信号,而其他组件可以监听这个信号并响应它。 下面是如…...
Elasticsearch中的动态DSL解决方案
目录 问题背景 解决方案 编写es的mapper 动态dsl编写 使用mapper获取动态dsl 远程调用restful api查询 问题背景 在大数据量的业务系统中,一般都会引入Elasticsearch来作为搜索引擎,而搜索的条件又是多种多样的。回顾下,如果是mysql等…...
【操作系统】MacOS虚拟内存统计指标
目录 命令及其结果 参数解读 有趣的实验 在 macOS 系统中,虚拟内存统计指标提供了对系统内存使用情况和虚拟内存操作的重要洞察。通过分析这些指标,我们可以更好地了解系统的性能状况和内存管理情况。 命令及其结果 >>> vm_stat Mach Virtu…...
LeetCode:67.二进制求和
67. 二进制求和 - 力扣(LeetCode) 又是一道求和题,% / 在求和的用途了解了些, 目录 题目: 思路分析: 博主代码: 官方代码: 每日表情包: 题目: 思路分析…...
修改GI文件的权限
参考文档: How to check and fix file permissions on Grid Infrastructure environment (Doc ID 1931142.1) -- 验证二进制文件的权限 [gridnode19c01 ~]$ cluvfy comp software -n node19c01 -verbosePerforming following verification checks ...Software …...
OJ刷题:杨氏矩阵【建议收藏】
看见这个题目,很多人的第一反应是遍历整个数组查找数字,但是这种方法不仅效率低,而且远远不能满足题目要求。下面介绍一种高效的查找方法: 代码实现: #include <stdio.h>int Yang_Find_Num(int arr[][3], int …...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...
