C++——内联函数

news2024/11/18 1:30:06

目录

1. 概念

2.特性

3. 经典面试题 

1. 概念

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

以Add函数为例:

int Add(int x, int y)
{
	int z = x + y;
	return z;
}

上述Add函数如若频繁调用,则效率上会存在一定的损失。假设我调用10次,那么就要建立十次栈帧,建立栈帧又要保存寄存器,压参数等等一系列操作都会造成效率损失。

  • 在先前学习的C语言中,就给出了解决方案:
#define ADD(x, y) ((x) + (y))
  • 既然用宏就可以解决,C++为何引出inline?

使用宏确实可以帮助我们避免调用栈帧继而不会造成效率损失,但是宏的写法上欠妥,我们需要注意结尾不能加分号,要注意优先级带来的问题而频繁加括号……C++为了填补宏书写规则麻烦的坑,专门出了一个更为方便书写的,也就是今个要谈论的内联函数(inline)。综上,结论如下:

  1. 解决宏函数晦涩难懂,容易写错的问题;
  2. 解决宏不支持调试,不支持类型安全的检查等问题。
  • 内联函数(inline)如何使用?

只需要在函数前面加上inline即可

inline int Add(int x, int y)
{
	int z = x + y;
	return z;
}

此时我们再调用函数就不会再建立栈帧了,函数直接会在调用的地方展开。

  • 内联函数(inline)如何支持调试的呢?

需要查看其反汇编,查看方式:

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

 

 

仔细看,此时每调用一次Add函数,均不会有call指令了, 此时再和我们没有加inline调用栈帧的版本对比下:

  •  综上:inline的好处如下:
  1. debug支持调试;
  2. 不易写错,就是普通函数的写法。

2.特性

  1. inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。
  2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。
  3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
  • 1、解释特性1和2:

假设我们现在有一个10行的函数,如若该函数有1000个调用的地方,如果inline替换,则是1000*10条指令,如果不替换,则是1000+10条指令,二者相差10倍之大,由此可见,代码很长或调用次数过多或存在循环/递归不适宜用内联函数

代码演示:

  • 代码演示:

 此段代码还能够证明inline对于编译器只是一个建议 。

  • 解释特性3:inline不建议声明和定义分离
// F.h文件
#include <iostream>
using namespace std;
inline void f(int i);
// F.cpp文件
#include "F.h"
void f(int i)
{
	cout << i << endl;
}
// test.cpp文件
#include "F.h"
int main()
{
	f(10);
	return 0;
}

此段代码中,inline函数的声明和定义分离,此时我们编译没有错误,可是在链接时发生错误:

原因如下:

F.h声明了我是一个内联函数,F.h文件会在F.cpp文件展开,要注意,inline函数在编译过程中不会生成地址,其符号表里没有地址,F.cpp文件中调用时找不到该函数地址。所以inline不建议声明和定义分离。

解决方法如下:

将声明和定义都放到F.h文件,就没有问题了,总之就是声明定义不能分离。

3. 经典面试题 

  • 问题1:宏的优缺点?

优点:

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

缺点:

  1. 不方便调试宏(因为预编译阶段进行了替换);
  2. 导致代码可读性差,可维护性差,容易误用;
  3. 没有类型安全的检查。
  • 问题2:C++有哪些技术代替宏?
  1. 常量定义,换用const;
  2. 函数定义,换用内联函数。

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

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

相关文章

RabbitMQ基础与实操复习

RabbitMQ基础复习 1、MQ引言1.1 什么是MQ1.2 MQ有哪些1.3 不同MQ特点 2、RabbitMQ引言2.1 RabbitMQ2.2 RabbitMQ安装 3、RabbitMQ配置3.1 RabbitMQ命令行3.2 Web管理界面3.2.1 overview概览3.2.2 Admin用户和虚拟主机管理 4、RabbitMQ常用消息模型测试4.1 RabbitMQ支持的消息模…

RabbitMQ应用场景和集群搭建复习

RabbitMQ应用场景和集群搭建 1. MQ的应用场景1.1 异步处理1.2 应用解耦1.3 流量削峰 2、RabbitMQ集群搭建2.1 普通集群(副本集群)2.1.1 架构图2.1.2 集群搭建1、集群规划&#xff1a;这里用三台虚拟机测试2、克隆三台机器主机名和ip映射3、 在其他两台节点上安装rabbitmq4、后台…

Neurophotonics | HyperOptoNet:用于fNIRS超扫描脑间神经同步分析的MATLAB工具箱

导读 意义&#xff1a;本研究开发了一个基于MATLAB的工具箱&#xff0c;用于脑间同步(IBS)分析&#xff0c;并进行了实验研究以验证其性能。据所知&#xff0c;这是第一个基于功能近红外光谱(fNIRS)超扫描数据的IBS工具箱&#xff0c;可在两个三维(3D)头部模型上直观地显示结果…

Elasticsearch:analyzer

前奏 es的chinese、english、standard等分词器对中文分词十分不友好&#xff0c;几乎都是逐字分词&#xff0c;对英文分词比较友好。 在kibana的dev tools中测试分词&#xff1a; POST /_analyze {"analyzer": "standard","text": "你太…

用OpenCV进行透视变换

1. 引言 欢迎回来&#xff01;今天我们将焦点聚焦在我在图像处理中最喜欢的话题之一——透视变换。使用该技术&#xff0c;可以灵活方便的实现各种各样好玩的特效。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2. 单应矩阵 我们首先展开对单应矩阵的深入研究。作为图…

车载-惯性导航系统

概念 惯性导航系统是一种不受电磁波干扰&#xff0c;且不依靠外界信号即可完成自主定位的导航系统。 惯性导航系统的主要定位测量装置由加速度传感器和陀螺仪组成。其中&#xff0c;加速度传感器是用来测量载体所受到的惯性力&#xff0c;并通过牛顿第二加速度定律获取被测载…

OpenGL 面剔除

1.简介 OpenGL能够检查所有面向观察者的面&#xff0c;并渲染它们&#xff0c;而丢弃那些背向的面&#xff0c;节省我们很多的片段着色器调用&#xff08;它们的开销很大&#xff01;&#xff09;。但我们仍要告诉OpenGL哪些面是正向面&#xff0c;哪些面是背向面。OpenGL使用…

Axure教程——走马灯

本文介绍用Axure中的动态面板制作走马灯效果 一、效果 预览地址&#xff1a;https://okjxsd.axshare.com 二、功能 1、图片自动播放并显示其状态 2、点击左右箭头&#xff0c;图片播放并显示其状态 三、制作 1、动态面板制作 拖进一个动态面板元件&#xff0c;设置尺寸&#…

RISC-V semi-hosting原理以及实践

嵌入式裸机调试需要在有限资源的目标硬件上尽可能挖掘更多的信息&#xff0c;比如打印寄存器等等&#xff0c;但是即便看似很简单的串口打印&#xff0c;在有的情况下也是奢望&#xff0c;针对这种情况&#xff0c;能够有效利用主机资源协同调试的semi-host&#xff08;半主机&…

B. Fish Graph(dfs找环)

Problem - 1817B - Codeforces 给定一个具有n个节点和m条边的简单无向图。请注意&#xff0c;该图不一定是连通的。节点从1到n标记。 如果图包含具有特殊节点u的简单循环&#xff0c;则定义图为Fish Graph。除循环中的边之外&#xff0c;图应恰好有2条额外的边。两条边都应连接…

设计模式之外观模式笔记

设计模式之外观模式笔记 说明Facade(外观)目录外观模式示例类图电灯类电视机类空调类智能音箱外观类测试类 说明 记录下学习设计模式-外观模式的写法。JDK使用版本为1.8版本。 Facade(外观) 意图:为子系统中的一组接口提供一个一致的界面&#xff0c;Facade模式定义了一个高…

【2023,学点儿新Java-23】初步了解Java中的修饰符:static及其作用、native特性、final的理解

前情回顾&#xff1a; 【2023&#xff0c;学点儿新Java-22】Java中package的作用是什么 | Java中import的用法 | Java中的权限修饰符&#xff1a;private、protected、public【2023&#xff0c;学点儿新Java-21】Java中default的语法格式 | 父类私有的方法能被重写吗&#xff…

三分钟学习一个python小知识3-----------我的对python的列表和元组的理解

我的目录 1、python是什么2、列表的应用3. 元组的应用&#xff1a;4、深层次地进一步理解列表和元组4.1. 列表示例&#xff1a;4.2. 元组示例&#xff1a; 总结 1、python是什么 在Python中&#xff0c;列表和元组都是用于存储多个数据项的数据结构&#xff0c;但是它们有一些…

JavaWeb Tomcat

1.Web分类 静态web html这样的静态网页&#xff0c;只展示预先设定好的内容每个用户看到的内容是一样的不连接数据库&#xff0c;无法持久化数据&#xff08;比如注册&#xff09;动态web 动态展示内容每个用户看到的内容是不一样的&#xff0c;比如会有个性化推荐连接数据库&…

TienChin 项目改造完善项目结构分析

项目改造完善 更改 Banner Banner 生成网站&#xff1a;https://bootschool.net/ascii 更改启动类中的 Banner !> 如果不生效&#xff0c;需要重新编译一下项目工程(出现了启动之后还没改变就需要执行一下这个步骤)&#xff1a; 出现的原因是可能你没有删除 .idea 文件与 .i…

夜不收见证:夫妻从内江到成都,从真诚到真相

他们从四川内江的一条小巷&#xff0c;走进了成都的大街小巷。那里的房屋挨挨挤挤&#xff0c;像是在讲述他们曾经的梦想和勇气。他们是那些在内江的土地上种下了友情种子的少年&#xff0c;他们在成都的大地上&#xff0c;硕果累累。 他们从初中的课桌前走到了成人的世界里&am…

模拟电路系列文章-滤波器常识

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 滤波是一个动作&#xff0c;对不同频率输入信号&#xff0c;实施不同的增益和相移&#xff0c;以形成输出。滤波器&#xff0c;是执行这种动作的硬件设备或者软件程序。无论滤…

DJ4-7 SDN、OpenFlow

目录 一、SDN 1、SDN 的引入 2、SDN 体系结构的特征 3、SDN 控制器 4、SDN 通用转发 二、OpenFlow 一、SDN 1、SDN 的引入 软件定义网络 (Software Defined Network) SDN 源自美国斯坦福大学 Clean Slate 研究组提出的一种新型网络创新架构&#xff0c;可通过软件编程…

OCC-BEV:基于三维场景重建的多摄像机统一预训练

论文&#xff1a;https://arxiv.org/pdf/2305.18829.pdf 代码&#xff1a;https://github.com/chaytonmin/Occ-BEV 多摄像机3D感知技术&#xff08;能够收集车辆周围360的环境信息&#xff09;已经成为自动驾驶领域的一个突出研究领域&#xff0c;为 Lidarb-based 解决方案提供…

EMC学习笔记(九)特殊信号的EMC处理(一)

特殊信号的EMC处理&#xff08;一&#xff09; 1.电源接口EMC防护滤波电路1.1 24VDC电源口1.2 电源地的EMC电路1.3 Flyback EMC电路1.4 BUCK电路EMC电路1.5 推挽电路 2.时钟电路的EMC防护2.1 有源时钟2.2 无源时钟2.3 差分时钟 3.复位电路EMC防护4.对外接口信号的EMC防护4.1 差…