[C++] 内联函数inline 以及 auto关键字 -- C++入门(4)

article/2025/9/17 3:58:05

本篇文章主要包括内联函数和auto关键字。其中,内敛函数包括概念,特性等;auto关键字的使用规则,使用场景等。

目录

1.内敛函数

1.1问题引入:

1.2内联函数的概念

1.3内敛函数的特性

2.auto关键字

2.1auto简介

2.2 auto的使用细则

2.3 auto不能推导的场景

2.4 auto与新式for循环使用

1.内敛函数

1.1问题引入:

我们在使用C语言中我们都学过函数,我们知道函数在调用的过程中需要开辟栈帧。如果我们需要频繁的调用一个函数,假设我们调用10次Add()函数,那我们就需要建立10次栈帧。我们都知道在栈帧中要做很多事情,例如保存寄存器,压参数,压返回值等等,这个过程是很麻烦的。那在C语言中,我们可以通过宏来解决这个问题。在C++中,我们便引入了内敛函数(inline)。

1.2内联函数的概念

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

我们这里依然使用Add()函数举例。这段代码是我们常写的Add()函数。假设我们多次调用Add函数,在C语言中,我们可以使用宏替换。在C++我们可以在函数前加上inline

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

C语言中用宏来代替Add函数: 

#define Add(x,y) ((x)+(y))

C++中在函数前加上inline使之成为内联函数

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

那C语言已经有了宏替换,为什么C++还要出现内联函数呢?

主要是有两个原因:

1.宏晦涩难懂不好控制,特别容易写错.语法机制设计不好。

2.宏不支持调试,但是内敛在debug下支持调试(在debug下不会展开,在release下才会展开),这样我们对代码的理解和掌握将大大提高。

如果在Add函数前增加 inline 关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。
查看方式:
1. release 模式下,查看编译器生成的汇编代码中是否存在 call Add
2. debug 模式下,需要对编译器进行设置,否则不会展开 ( 因为 debug 模式下,编译器默认不会对代码进 行优化,以下给出 vs2019 的设置方式 )

 

 

1.3内敛函数的特性

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

这里代码多长算长呢?  一般是10行左右,具体取决于编译器。

1.3.2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。

这里可以举个例子,假设我们有一个代码需要10行,但是我们需要调用1000次。如果inline替换的话,我们要有1000*10条指令,如果不替换则有1000+10条指令。因此最终是否替换,取决于编译器。

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

我们发现,虽然Add函数前加了inline,但是最终却没有展开。

3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到

 我们在f.cpp中调用一下:发现报错了

 在这里他就会发生链接错误:

 这是因为test.h中替换到test.cpp中发现是内联函数,内联函数不需要生成地址,因为内联函数调用的地方都展开了,因此不会存在在符号表中。外部调用时就找不到。因此不要将声明和定义分开。

2.auto关键字

2.1auto简介

在早期 C/C++ auto 的含义是:使用 auto 修饰的变量,是具有自动存储器的局部变量。C++11中,标准委员会赋予了auto 全新的含义即: auto 不再是一个存储类型指示符,而是作为一个新的类型 指示符来指示编译器, auto 声明的变量必须由编译器在编译时期推导而得

auto在C语言中我们是接触过的:最宽宏大量的关键字,由于局部变量默认都是auto修饰的,因此auto可以省略,这就导致auto常常被人忽略。那么在C++11中,auto进行了升级,有了新的功能--自动推导。(注意:auto新功能只是在C++11之后才有此功能)

 那么auto是怎么自动推导呢?

我们可以使用typeid,来打印一个变量的类型。

int main()
{const int  a = 10;auto b = &a;auto c = 'a';cout << typeid(b).name() << endl;//typeid可以打印一个变量的类型cout << typeid(a).name() << endl;//typeid可以打印一个变量的类型cout << typeid(c).name() << endl;//typeid可以打印一个变量的类型return 0;
}

我们发现auto的自动推导还是很智能的。

auto意义之一:类型很长时,懒得写,可以让他自动推导

注意:

使用 auto 定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导 auto 的实际类 。因此 auto 并非是一种 类型 的声明,而是一个类型声明时的 占位符 ,编译器在编译期会将 auto 替换为 变量实际的类型

2.2 auto的使用细则

1. auto与指针和引用结合起来使用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&.
int main()
{int x = 10;auto a = &x;auto& c = x;cout << typeid(x).name() << endl;//typeid可以打印一个变量的类型cout << typeid(a).name() << endl;//typeid可以打印一个变量的类型cout << typeid(c).name() << endl;//typeid可以打印一个变量的类型return 0;
}
2. 在同一行定义多个变量当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量
	auto a = 1, b = 2;auto c = 3, d = 4.0;//c和d类型不同,auto推导会冲突的

 

2.3 auto不能推导的场景

1. auto不能作为函数的参数

// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}

 

 2. auto不能直接用来声明数组

void TestAuto()
{int a[] = { 1,2,3 };auto b[] = { 4,5,6 };
}

2.4 auto与新式for循环使用

在平常我们打印一个array数组,我们需要依次打印遍历。如下代码所示:

int main()
{int array[] = { 1,2,3,4,5 };for (int i = 0; i < sizeof(array) / sizeof(int); ++i)array[i] *= 2;for (int i = 0; i < sizeof(array) / sizeof(int); ++i)cout << array[i] << " ";cout << endl;return 0;
}

我们也可以使用auto结合范围for循环打印这个数组:

	for (auto e : array)cout << e << " ";cout << endl;

在这里我们使用到了一个新的for循环,范围for。它会依次自动取array中的数据,赋值给e,并且会自动判断结束,因此我们使用auto可以自动识别数组元素的类型。

注意:e只是array的拷贝,改变e不会改变array数组的内容。如果我们想改变array的内容,只需要加个引用即可,意思是让e成为array的别名,代码如下:

	//加个引用就可以访问到arrayfor (auto& e : array){e /= 2;}for (auto e : array)cout << e << " ";

(本篇完)


http://chatgpt.dhexx.cn/article/MQqpVDZw.shtml

相关文章

Windows误删注册表恢复方法

昨天不小心把注册表给删了,期间一直找解决方法,因为没有usb等重装工具... 我把注册表的HKEY_LOCAL_MACHINE\software这个重要的东西给误删了 ---结果就是软件打不开.就连删除东西都没用,自带的cmd什么的系统工具打不开... 关机重启问题更严重了,直接蓝屏,但是还好,开机的时候…

Linux 误删文件恢复命令及方法

你知道的越多&#xff0c;不知道的就越多&#xff0c;业余的像一棵小草&#xff01; 你来&#xff0c;我们一起精进&#xff01;你不来&#xff0c;我和你的竞争对手一起精进&#xff01; 编辑&#xff1a;业余草 http://r6d.cn/JzNf 推荐&#xff1a;https://www.xttblog.com/…

win10误删的注册表能还原吗_win10自带注册表恢复方法 win10注册表误删如何修复...

系统注册表&#xff0c;是计算机中一个很重要的部件&#xff0c;没有人可以保证自己能记住所有的注册表项&#xff0c;如果不小心让注册表被修改或者其他原因让注册表失效的时候&#xff0c;我们就可以通过cmd对注册表进行恢复&#xff0c;下面小编就为大家介绍win10自带注册表…

成功恢复 Linux 系统中已删除的文件

点击关注公众号&#xff0c;回复“1024”获取2TB学习资源&#xff01; 当用户意外地删除了一个仍然需要的文件时&#xff0c;大多数情况下&#xff0c;是没有简便的方法可以重新找回或重建这个文件。不过&#xff0c;幸运的是文件是可以通过一些方法恢复的。当用户删除了一个文…

windows注册表操作——备份,还原注册表,清除注册表卸载残留信息

注册表包含在操作过程中Windows不断引用的信息&#xff0c;例如每个用户的配置文件、计算机上安装的应用程序以及每个用户可以创建的文档类型、文件夹和应用程序图标的 属性表 设置、系统上存在的硬件以及所使用的端口。 序言 注册表是Microsoft Windows中的一个重要的数据库…

Linux下达梦误删除文件后恢复步骤

目录 数据文件恢复1.测试环境准备2.删除数据文件3.恢复步骤4.使用限制5.官方资料 redo日志恢复1. 删除redo日志2.启动数据库3.查看建库参数4.初始化新实例5.拷贝redo文件6.修改db_magic值7.启动数据库8.错误示范9.迁移数据 官方社区 数据文件恢复 1.测试环境准备 1.1准备好测…

windows注册表恢复方法

如果可以进入安全模式&#xff0c;您可以在安全模式内调用命令提示符输入命令修复一下系统组件。 在管理员命令提示符下键入以下命令&#xff1a; Dism /Online /Cleanup-Image /ScanHealth 这条命令将扫描全部系统文件并和官方系统文件对比&#xff0c;扫描计算机中的不一致…

linux环境下恢复rm误删的文件

文章目录 前言rm之后还有救吗使用foremost找回文件使用extundelete找回文件 预防误删引发的事故总结 前言 一提到在 linux 环境下删除文件&#xff0c;那绝对离不开 sudo rm -rf /* 这个梗&#xff0c;每次看到这个命令&#xff0c;我都想到一幅恶搞的图片&#xff1a; 这个『…

如何恢复 Linux 系统下被删除的文件 ?

丢失数据是任何用户都可能经历的最令人不安和痛苦的经历之一。一旦珍贵数据被删除或丢失&#xff0c;就再也找不不回来通常会引发焦虑&#xff0c;让用户感到无助。值得庆幸的是&#xff0c;有几个工具可以用来恢复 Linux 机器上被删除的文件。我们尝试了一些数据恢复工具&…

入门版Linux上恢复误删除的文件

一、被删除的文件正在被进程使用&#xff1a; 当某个文件正在被某个程序使用时&#xff0c;linux针对该文件有回两个计数器&#xff1a; i_count计数器&#xff1a;该文件可能被多个进程使用&#xff0c;每一个进程使用该文件&#xff0c;i_count数值都会加1。反之&#xff0…

不小心误删注册表exe,所有exe程序无法运行

首先我陈述下误删的原因吧&#xff0c;与其说是误删不如说就是自己有 意删除的&#xff0c;电脑Windows7&#xff0c;我在安装CASS10.1的时候&#xff0c;由于一个补丁程序始终不能运行&#xff0c;弹框显示说CASS10.1.6补丁.exe不是有效的Win32应用程序。然而我去寻找解决办法…

如何恢复Linux中的误删文件

写在前面的话 在开始教程之前我有必要提醒大家&#xff0c;使用窗口管理器&#xff08;GUI&#xff09;删除文件和使用命令行工具&#xff08;CLI&#xff09;删除文件这两种方法之间是有区别的。 当我们使用窗口管理器来删除文件时&#xff0c;我们仅仅只是将文件从某个目录移…

Win11注册表编辑器误删了如何恢复?

​ 注册表编辑器是一个用来更改系统注册表设置的高级工具&#xff0c;与资源管理器的界面很类似。近期有用户将注册表编辑器误删了&#xff0c;那么应该如何恢复呢&#xff0c;下面小编就给大家分享一下详细的恢复方法。遇到同样问题的用户注意了。 更多重装系统教程尽在小白…

注册表中exe被删除后恢复

恢复注册表 如果我们不小心将注册表中的exe删除后&#xff0c;这个时候不管打开什么软件都需我们自己进行指定才能打开使用&#xff0c;这样是及其麻烦的&#xff0c;而且在删除掉.exe之后&#xff0c;原来能在“运行”中搜索的执行文件也都无法执行了&#xff0c;比如果原来我…

LINUX使用rm误删文件后恢复

最近使用centos执行了rm -rf删除了一个文件&#xff0c;后面想恢复。 先关闭selinux vim /etc/selinux/config SELINUXdisabled reboot 重启生效1、使用debugfs命令恢复&#xff08;此命令为系统自带&#xff09; 1-1、查看文件系统类型&#xff0c;以下2个命令都可查看&…

电脑注册表误删恢复办法:系统文件和设置还原法

一.起因&#xff1a;为了修改电脑字体一不小心把Control Panel整个注册表给删除了&#xff0c;导致电脑界面变的锯齿&#xff0c;界面变形等各种问题&#xff0c;网上找了许多方法都没成功或者难度较大&#xff0c;最终使用系统恢复还原点将系统变成几个小时前的各种设置&#…

如何每天自动发送心灵鸡汤、正能量语录

为什么要发送心灵鸡汤、正能量语录 许多团队管理者或者行政为了需要鼓励团队&#xff0c;让员工有一个积极饱满的工作状态&#xff0c;需要每天在企业群内发送心灵鸡汤、正能量语录等信息&#xff0c;按照大多数人的办法&#xff0c;是在搜索引擎找到对应的心灵鸡汤或者正能量…

励志心灵鸡汤经典语录,满满都是道理!

1、【人生的幸运是靠努力而来的&#xff0c;世上没有不劳而获&#xff0c;天上掉馅饼的事&#xff0c;所谓种瓜得瓜&#xff0c;种豆得豆。别人可以替你开车&#xff0c;但不能替你走路&#xff1b;可以替你做事&#xff0c;但不能替你感受。人生的路要靠自己去走&#xff0c;成…

隐马尔可夫模型前向算法推导

已知条件有&#xff1a; 状态集合&#xff1a;&#xff0c;观测集合&#xff1a; 已观测到的观测序列 从t时刻的状态到t1时刻的状态的状态转移概率&#xff1a; 从t时刻的状态生成t时刻的观测的概率&#xff1a; 状态初始概率向量 给定隐马尔可夫模型 &#xff0c;定义到…

隐马尔可夫模型的三个基本问题

目录 写在前面的话隐马尔可夫模型&#xff08;HMM&#xff09;隐马尔可夫模型的三个基本问题 写在前面的话 隐马尔可夫模型&#xff08;HMM&#xff09;的三个基本问题&#xff0c;我查阅相关资料有一些自己的理解&#xff0c;如有错误请多指正~ 参考资料&#xff1a; 如何用…