【C++函数探幽】内联函数inline

news2024/11/26 8:19:47

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


在这里插入图片描述


目录

  • 1. 前言
  • 2.概念
  • 3.特性
  • 4.内联与宏


1. 前言

内联函数是C++为提高程序运行速度所做的一项改进。常规函数和内联函数之间的主要区别不在于编写方式,而在于C++编译器如何将他们组合到程序中。要了解内联函数与常规函数之间的区别, 必须深入到程序内部。

编译过程的最终产品是可执行程序——由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。有时(如有循环或分支语句时),将跳过一些指令,向前或向后跳到特定地址。常规函数调用也使程序跳到另一个地址(函数的地址),并在函数结束时返回。执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈(为此保留的内存块),跳到标记函数起点的内存单元,执行函数代码(也许还需将返回值放入到寄存器中),然后跳回到地址被保存的指令处(这与阅读文章时停下来看脚注,并在阅读完脚注后返回到以前阅读的地方类似)。来回跳跃并记录跳跃位置意味着以前使用函数时,需要一定的开销。

C++内联函数提供了另一种选择。内联函数的编译代码与其他程序代码“内联”起来了。也就是说,编译器将使用相应的函数代码替换函数调用。对于内联代码,程序无需跳到另一个位置处执行代码,再跳回来。因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存。如果程序在10个不同的地方调用同一个内联函数,则该程序将包含该函数代码的10个副本(参见下图)。

在这里插入图片描述

应有选择地使用内联函数。如果执行函数代码的时间比处理函数调用机制的时间长,则节省的时间将只占整个过程的很小一部分。如果代码执行时间很短,则内联调用就可以节省非内联调用使用的大部分时间。另一方面,由于这个过程相当快,因此尽管节省了该过程的大部分时间,但节省的时间绝对值并不大,除非该函数经常被调用。


2.概念

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调
用建立栈帧的开销,内联函数提升程序运行的效率。
查看方式:

  1. 在release模式下,查看编译器生成的汇编代码中是否存在call Add
  2. 在debug模式下,需要对编译器进行设置,否则不会展开(因为debug模式下,编译器默认不
    会对代码进行优化,以下给出vs2013的设置方式)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


3.特性

  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会
    用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运
    行效率。
  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建
    议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不
    是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性
  3. 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.没有类型安全的检查 。

内联是传递表达式,所以不会出现使用宏所导致的错误
通过对比可以看到,内联功能是远远超过宏定义的,我们在学习中要多去将以前使用宏定义的地方多去考虑使用内联函数

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

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

相关文章

位图

目录 位图的概念 位图的实现 寻找位置 set reset test 面试题 1.给定100亿个整数,设计算法找到只出现一次的整数? 2. 给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集? 3. 位…

SpringBoot Starter造了个自动锁轮子

可能有人会有疑问,为什么外面已经有更好的组件,为什么还要重复的造轮子,只能说,别人的永远是别人的,自己不去造一下,就只能知其然,而不知其所以然。(其实就为了卷) 在日常…

VS Code之Java代码重构和源代码操作

文章目录 支持的代码操作列表调用重构分配变量字段和局部变量的差别Assign statement to new local variable在有参构造函数中将参数指定成一个新的字段 将匿名类转换为嵌套类什么是匿名类?匿名类转换为嵌套类的完整演示 转换为Lambda表达式Lambda 表达式是什么?转…

【OrangePi Zero2 智能家居】智能家居项目的软件实现

一、项目整体设计 二、项目代码的前期准备 三、实现语音监听接口 四、实现socket监听接口 五、实现烟雾报警监听接口 六、实现设备节点代码 七、实现接收消息处理接口 一、项目整体设计 整体的软件框架大致如下: 整个项目开启4个监听线程, 分别是&…

Java常用类与基础API--String的构造器与常用方法

文章目录 一、String的常用API-1(1)构造器1、介绍2、举例 (2)String与其他结构间的转换1、基本数据类型、包装类 --> 字符串2、字符串 --> 基本数据类型、包装类3、字符串 --> 字符数组4、字符数组 --> 字符串5、字符…

C++类和对象-C++运算符重载->加号运算符重载、左移运算符重载、递增运算符重载、赋值运算符重载、关系运算符重载、函数调用运算符重载

#include<iostream> using namespace std; //加号运算符重载 class Person { public: Person() {}; Person(int a, int b) { this->m_A a; this->m_B b; } //1.成员函数实现 号运算符重载 Person operator(const Per…

4核16G服务器价格腾讯云PK阿里云

4核16G服务器租用优惠价格26元1个月&#xff0c;腾讯云轻量4核16G12M服务器32元1个月、96元3个月、156元6个月、312元一年&#xff0c;阿腾云atengyun.com分享4核16服务器租用费用价格表&#xff0c;阿里云和腾讯云详细配置报价和性能参数表&#xff1a; 腾讯云4核16G服务器价…

JavaWeb学习|Filter与ThreadLocal

学习材料声明 所有知识点都来自互联网&#xff0c;进行总结和梳理&#xff0c;侵权必删。 引用来源&#xff1a;尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版 Filter 1、Filter 过滤器它是 JavaWeb 的三大组件之一。三大组件分别是&#xff1a;Servlet 程序、Liste…

Oracle数据库自动维护任务(Automated Maintenance Tasks)

Oracle数据库自动维护任务(Automated Maintenance Tasks) Oracle数据库有以下预定义的自动维护任务: Automatic Optimizer Statistics Collection - 收集数据库中没有统计信息或只有过时统计信息的所有模式对象的优化器统计信息。SQL查询优化器使用该任务收集的统计信息来提高…

数学实验第三版(主编:李继成 赵小艳)课后练习答案(十)(2)(3)

实验十&#xff1a;非线性函数极值求解 练习二 1.求解极值问题: (1) s.t. function [c,ceq]fun(x) c(1)-(25-x(1)^2-x(2)^2); c(2)-(7-x(1)^2x(2)^2); ceq0;换一个窗口运行下面的程序&#xff1a; clc;clear; f(x)-2*x(1)-x(2); a[]; b[]; aeq[];beq[]; u[5;10]; l[0;0];…

一起玩儿Proteus仿真(C51)——06. 红绿灯仿真(二)

摘要&#xff1a;本文介绍如何仿真红绿灯 今天来看一下红绿灯仿真程序的具体实现方法。先来看一下整个程序的原理图。 在这个红绿灯仿真实验中&#xff0c;每个路口需要控制的设备是2位数码管显示倒计时以及红黄绿灯的亮灭。先来看一下数码管的连接方法。 数码管的8根LED显示…

解决Windows更新后无法启动的十种办法,总有一种适合你

你可能已经更新了操作系统以修复错误或使用最新功能。但是,如果Windows在更新后无法启动呢? 如果你面临这样的问题,主要是由于安装文件中的错误或你的系统与最新更新不兼容。此外,损坏的MBR或驱动程序也会阻止电脑启动。 不管是什么原因,本文将用十种简单的技术来指导你…

【蓝桥杯单片机入门记录】认识单片机

目录 单片机硬件平台 单片机的发展过程 单片机开发板 单片机基础知识 电平 数字电路中只有两种电平&#xff1a;高和低 二进制&#xff08;8421码&#xff09; 十六进制 二进制数的逻辑运算 “与” “或” “异或” 标准C与C51 如何学好单片机 端正学习的态度、培…

2024年云南省考报名详细流程图解,招聘5710人!

云南省考公告出来了&#xff01;招5710人&#xff01; ✔️报名时间&#xff1a;2024年2月19日9:00至2月23日18:00 ✔️缴费时间&#xff1a;2024年2月20日0:00至2月25日24:00 ✔️公共科目笔试时间为&#xff1a; 2024年3月16日上午 9:00&#xff0d;11:00 行政职业能力测验 2…

【leetcode热题100】不同的二叉搜索树

给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;5示例 2&#xff1a; 输入&#xff1a;n 1 输出&#xff1a;1 …

平时积累的FPGA知识点(7)

平时在FPGA群聊等积累的FPGA知识点&#xff0c;第七期&#xff1a; 11 描述扇出的xilinx官方文档是&#xff1f; 解释&#xff1a;ug949 12 在BD中如何指定某个IP用global&#xff0c;其他的用OOC模式&#xff1f;因为某个模块引用的IP带着XPM&#xff0c;综合不了 解释&am…

【MySQL】高度为2和3时B+树能够存储的记录数量的计算过程

文章目录 题目答案高度为2时的B树高度为3时的B树总结 GPT4 对话过程 题目 InnoDB主键索引的Btree在高度分别为 2 和 3 时&#xff0c;可以存储多少条记录&#xff1f; 答案 高度为2时的B树 计算过程&#xff1a; 使用公式 ( n 8 ( n 1 ) 6 16 1024 ) (n \times 8 …

ELAdmin 隐藏添加编辑按钮

使用场景 做了一个监控模块&#xff0c;数据都是定时生成的&#xff0c;所以不需要手动添加和编辑功能。 顶部不显示 可以使用 true 或者 false 控制现实隐藏 created() {this.crud.optShow {add: false,edit: false,del: true,download: true,reset: true}},如果没有 crea…

python守护进程--supervisor 使用教程

supervisor 使用教程python守护进程1.安装 pip3 install supervisor -i https://pypi.tuna.tsinghua.edu.cn/simple 2.使用supervisor 启动 python main.py 文件 vim /etc/supervisor/conf.d/demo.conf添加以下内容&#xff1a;[program:demo] #项目名称为democommandp…

oppo手机QQ上传文件所在位置

一、打开手机“文件管理”APP 点击“点击查看”&#xff0c;按钮&#xff0c;会进入到新的根目录。 寻找下面的目录进入