【C++入门】你知道C++为什么会有内联函数吗?

news2024/7/4 6:33:11

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


前言

本章是补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的。

目录

  • 前言
  • 一、问题引入
  • 二、内联函数的概念
  • 三、内联函数的特性
  • 四、面试题

一、问题引入

我们每次去调用函数的时候,都会有消耗(建立栈帧等等)。假设我现在要调用100次Add函数,那么就要建立100个栈帧

在这里插入图片描述

在C语言中,为了防止如此大的消耗,我们通常用宏函数来解决问题。宏函数的优势:不需要建立栈帧,提高调用效率。

在这里插入图片描述

这里就得提提宏函数书写的经典错误了 (面试常考!!!)

  1. 宏代码本身不是函数,它是一种替换,因此不需要类型
  2. 末尾不需要分号
  3. 括号问题
    ①有的人可能会这么写#define Add(x, y) x+y,那么如果有人给出这么一串代码Add(1, 1) * 2就会出现问题。原因是:宏替换后就会变成—>1 + 1 * 2,而我们期望的是先算1 + 1,然而宏替换后,根据运算符的优先级,它会先算1 * 2
    ②还有的人可能会这么写#define Add(x, y) (x+y),那么如果有人给出这么一串代码Add(a|b, a&b) 就会出现问题。原因是:宏替换后就会变成–>(a|b + a&b),所以说,它还是因为优先级的问题,我们期望是先计算出a|ba&b,然而,根据运算符的优先级,它会先算b+a

宏既然有优点,那一定就会有缺点(复杂、不易调试、代码可读性差),那就是特别容易书写写错误。因此,Bjarne Stroustrup大佬看不下去了,于是自创了一个新语法 — 内联函数

二、内联函数的概念

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

所以,在【问题引入】中,用内联函数表示方法如下:

在这里插入图片描述

通过以上代码,我们可以看出内联函数的优点是(解决了宏的缺点):
①不需要建立栈帧
②不复杂、不容易出错、可读性好、容易调试

三、内联函数的特性

有的人说,既然内联函数这么好,那可不可以将所有的函数都内联函数来表示?答案是当然不行,会导致代码膨胀(下面第一点会解释)!内联函数值适用于短小其频繁调用的函数

  1. inline是一种以空间换时间的做法。假如有一个Func函数有50行指令,假设某个项目要调用1wFunc函数,如果不使用内联函数,就会有1w+50行指令;如果使用内联函数,在编译阶段,会用函数体替换函数调用,就会1w*50行指令,这会导致最后可执行程序(安装包)变大,谁会希望一个程序的安装包大呢?这就是代码膨胀,因此不能让所有的函数变成内联函数

  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,最终是否会称为inline,编译器自己决定

如果在函数前增加inline关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。
VS编译器的查看方式:

  1. release模式下,查看编译器生成的汇编代码中是否存在call xxx
  2. debug模式下,inline不起作用,否则不方便调试了,但是在release下又不方便看反汇编,所以可以稍微更改VS的属性来查看,步骤如下:

右击项目,点击属性

在这里插入图片描述
在属性页中点击C/C++,对常规进行更改如下:
在这里插入图片描述
然后再点击优化,更改操作如下:
在这里插入图片描述
最后点击应用即可,然后我们就可以进入调试(F10)反汇编查看(右击即可查看)了,下面就是内联函数的调用,只要我们没有观察到call xxx就代表着是内联函数了
在这里插入图片描述
当然,我们可以增加代码行,即使是加了inline,编译器也不会支持
在这里插入图片描述

  1. inline不建议声明和定义分离

在这里插入图片描述

看似没错,其实程序最后会报错

在这里插入图片描述

这是因为:分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到

所以内联函数的定义和声明一定要在一起

在这里插入图片描述

四、面试题

宏的优缺点?
优点:

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

缺点:

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

C++有哪些技术替代宏?

  1. 常量定义 换用const enum
  2. 短小函数定义 换用内联函数

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

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

相关文章

深度优先遍历和广度优先遍历

深度优先遍历和广度优先遍历 文章目录 深度优先遍历和广度优先遍历图图的实现遍历方式深度优先遍历基本思想广度优先遍历基本思想 完整代码 图 介绍:用于表示多对多的关系 图是一种数据结构,其中结点可以具有零个或多个相邻元素。两个结点之间的连接称…

FFmpeg AAC 解码 PCM

1. 概要与流程图 1.1 AAC 转 PCM,需要解码库来实现,目前了解有三种方式,当前使用的是 FFmpeg 库解码 1) faad 解码库网址:faadhttps://sourceforge.net/projects/faac/files/faad2-src/ 2) fdk-aac 编解码库网址: fdk-aac

接口测试入门:轻松掌握 ,让你的后端“心甘情愿”地配合你

目录 前言 简介 什么是API测试? API测试的必要性 API测试的类型 优势 API测试的挑战 【自动化测试工程师学习路线】 前言 在这篇文章中,我将带你轻松入门接口测试并掌握实用技巧,让你能够与后端开发人员更加顺畅地合作。相信我&…

【量化分析】用mplfinance显示交易图时,处理 Expect data.index as DatetimeIndex?

目录 一、说明 二、程序代码和出错描述 三、合理化建议 3.1 读入数据时指定索引 3.2 读入数据后,使用数据前指定日期(时间戳)索引 一、说明 我打算从比特币数据中获取烛台图。这是我在加载 csv 文件后选择我想要的数据框的代码。然而&…

【2】Kaggle:狗的种类识别,基于论文中的 VGG(11)/ResNet(18)/SENet 结构实现

1.数据集格式 在前面【1】中已经对数据集进行过了处理,在自己实现这一模块,训练数据集的统一格式为下图: 2.VGG11结构 根据论文Karen Simonyan, Andrew Zisserman. Very deep convolutional networks for large-scale image recognition. ICLR, 2015. (VGG) 中的结构,根…

如何在华为云服务器安装MindSpore框架

参考链接 一、获取安装命令 我是在华为云租了一个云服务器,然后系统是Ubuntu18.04,如果不知道自己的系统,可以通过以下方式: 第三方依赖安装方法 1.确认安装Ubuntu 18.04是64位操作系统 确认系统版本号,在终端输入lsb_release…

Linux -- 进阶 Web服务器 虚拟主机 --- 基于 IP 地址

虚拟主机 一个Web 服务器,如果只能运行一个网站的话,那么对于一些经费不是很足的小公司来说,那就 有些奢侈了,资源没有办法完全利用上 ( 无论是 内存,CPU,硬盘,带宽等等 &#xff0…

【网络常用命令汇总】ping和ipconfig命令、nslookup命令、netstat和tracert命令、route和arp命令详解(附图详解)

【写在前面】由于考试将近我也是临时抱个佛脚,之前对网络这块的概念真的只是停留在大学里面学的计算机网络,但是当时并没有接触这些实在的东西,也就只有工作后才会去想那么多,比如网络连通性ping一下就知道,其他的更不…

第07讲:Java High Level Client,读写 ES 利器

SkyWalking OAP 后端可以使用多种存储对数据进行持久化,例如 MySQL、TiDB 等,默认使用 ElasticSearch 作为持久化存储,在后面的源码分析过程中也将以 ElasticSearch 作为主要存储进行分析。 ElasticSearch 基本概念 本课时将快速介绍一下 E…

【类和对象完结篇】

目录 ❀初始化列表 构造函数体赋值 初始化列表 ❀explicit关键字 ❀static成员 什么是static成员? 特性 ❀友元 友元函数 友元类 ❀内部类 ❀理解类和对象 🍀​​​​​​​​​​​​​​小结🍀 🎉博客主页&#xf…

linux环境安装使用mysql详解

01-安装MySQL并启动 1.1 环境准备 # 1.卸载mariadb,否则安装mysql会出现冲突 (1).执行命令rpm -qa | grep mariadb 会列出所有被安装的mariadb rpm 包; (2).执行命令rpm -e --nodeps mariadb-libs-5.5.56…

super_排列组合lesson08易错题记录

此题用插空法解决:这个是组合的问题,总共10个学生,要分配到7个班级里,也就是要把这十个学生分为7部分,如果让学生们站在一起,就是在9个空位中插入6块木板,也就是C(9,6)也就是84 此题用捆绑法解决…

[Java进阶] 线程池详解

文章目录 前言1. 线程池的作用2. 线程池的应用3. 标准库中创建线程池的方式 前言 本文介绍线程池的作用和实现方法. 1. 线程池的作用 1.我们知道,线程的作用是由于进程的创建和销毁需要分配和回收资源,开销较大.而线程是"轻量级进程",创建销毁更高效. 2.线程池,比线…

汽车发动机点火性能测试仪设计

汽车发动机的点火系统包括上百种电气和机械零部件,生产线分布较广,因此分布式间接监控方式在点火系统的监测与故障诊断系统中得到广泛应用。发动机点火性能测试仪通过测量发动机的闭合角与分火角,对其分电器和点火器性能进行分析。 闭合角、分…

Python接口自动化测试实战系列

本节内容 接口及接口测试 网络基础知识:IP,域名, DNS及端口 网络基础知识:OSI七层模型及TCP协议 HTTP协议 接口及接口测试 这里插播一个段子 上图中,程序员口中提到的接口是什么意思呢? 手机壳有没有颜色这个属性&#xff0…

安全渗透工程师入门最快需要多久?提供具体路线和学习框架

前言 网络渗透这个东西学起来如果没有头绪和路线的话,是非常烧脑的。最快达到入门也要半年 理清网络渗透学习思路,把自己的学习方案和需要学习的点全部整理,你会发现突然渗透思路就有点眉目了。 网络安全好混,但不容易混得好。…

【顶配快速排序】CUTOFF配合三点中值法的三路划分

目录 1引入情境2 形式化描述2-1递归结构2-2 一次划分2-3 C实现 3 在工程中的改进3-1 处理重复元素双向划分三路划分C 实现 3-2 最差情况的改进三点中值法随机选择pivot短序列切回插入排序 4 全部改进技术加持 1引入情境 从低到高排成一队,怎么办? 以大雄…

RIME协议栈解读

// 新坑–contiki rime简介 rime类似于TCP/IP协议栈,属于分层结构。图片来自Adam Dunkels本人的rime论文介绍。 abc为anonymous broadcast,匿名广播。即将数据包通过无线射频驱动(radio driver)发出去,接收来自无线射频驱动所有的包并交给…

四月成功上岸阿里,年后准备了两个月,要个21k应该不过分吧~

先说下我基本情况,本科不是计算机专业,现在是学通信,然后做图像处理,可能面试官看我不是科班出身没有问太多计算机相关的问题,因为第一次找工作,阿里的游戏专场又是最早开始的,就投递了&#xf…

[JAVA数据结构]希尔排序/缩小增量法

前置内容:[JAVA]直接插入排序_HY_PIGIE的博客-CSDN博客 希尔排序,是将一个数组分成多组,在每一个组内进行排序。每进行一次排序,组中的元素都会增多,组数减少。 在组内进行直接插入排序 组数以/2的形式减少 例入&#…