【C++从练气到飞升】23--内联函数、auto、范围for、nullptr

news2024/9/22 19:42:44

 🎈个人主页:库库的里昂
收录专栏:C++从练气到飞升
🎉鸟欲高飞先振翅,人求上进先读书🎉

目录

⛳️推荐

一、内联函数

1.1 定义

1.2 特性

二、auto关键字

2.1 简介

2.2 auto使用细则

2.3 不能使用auto的场景

三、基于范围的for循环

3.1 范围for的使用条件

四、指针空值nullptr


⛳️推荐

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

一、内联函数

 普通的函数在调用的时候会开辟函数栈帧,会产生一定量的消耗,在C语言中可以用宏函数来解决这个问题,但是宏存在以下缺陷:复杂、容易出错、可读性差、不能调试。为此,C++中引入了内联函数这种方法。

1.1 定义

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

int Add(int x, int y)//这里的Add是一个普通函数
{
	return x + y ;
}

int main()
{
	int ret = 0;
 	ret = Add(3, 5);
	cout << ret << endl;
	return 0;
}

🪆内联函数:

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

int main()
{
	int ret = 0;
 	ret = Add(3, 5);
	cout << ret << endl;
	return 0;
}

注意:在默认的Debug模式下,内联函数是不会展开的,需要进行设置,设置过程如下:

1.2 特性

  • inline是一种以时间换空间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用缺陷:可能会使目标文件变大,优点:少了调用开销,提高程序运行效率。
  • inline对编译器而言只是建议,不同的编译器关于inline的实现机制可能不同,一般建议:将函数规模小的(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
  • inline建议函数声明和定义不能分离,因为内联函数在预处理阶段就直接展开,因此内联函数不会进符号表,因此如果声明和定义分离,头文件只有声明,在预处理阶段,头文件展开,只知道该函数是一个内联函数,没有对应函数的定义,因此就无法完成替换,那就只能等通过call在链接阶段去找该函数,但是它是内联函数,没有进符号表,所以链接阶段就会报错。

🪆为什么是函数规模小?
 假设一个函数经过编译,得到五十条汇编指令。普通情况下,调用此函数只需要一条call指令,调用10000此也就10000条call指令,但是如果把这个函数设置成内联函数,指令的数量就会大大增加,因为内联函数完成的是替换,把所有调用它的地方,都用函数体去替换,这也就意味着,原来1条call指令就能完成的任务,现在替换后就变成了50条指令,假如还是调用了10000次该函数,那就从10000条call指令,变成了500000条指令,其实这就是代码膨胀

inline int Add(int x, int y)
{
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	cout << "xxxxxxxxxxxx" << endl;
	return x + y ;
}

int main()
{
	int ret = 0;
 	ret = Add(3, 5);
	cout << ret << endl;
	return 0;
}

 对于上面函数体比较长的函数,即使我们人为规定了它是内联,但最终还是通过call指令去调用函数。

🪆为什么是被频繁调用?
 因为普通函数在调用的时候会创建函数栈帧,若频繁调用就会频繁的创建栈帧,增加消耗。宏和内联,就是为了解决开销问题。如果调用的次数不多,开辟一点栈帧是无所谓的。

二、auto关键字

2.1 简介

C++11中规定:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。简单来说,auto会根据表达式自动推导类型。

int main()
{
	int a = 0;
	auto b = a;//自动推导出b的类型是int
	auto c = 1.11 + 1;//自动推导出c的类型是double
	cout << typeid(b).name() << endl;//typeid可用来查看变量类型
	cout << typeid(c).name() << endl;
	return 0;
}

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

int main()
{
	auto a;//错误,必须要初始化
	return 0;
}

2.2 auto使用细则

🪆auto与指针和引用结合起来使用
 用auto声明指针类型时,用auto和aauto*没有任何区别,但是auto声明引用类型时,必须要加&,如下,如果c不加&的话,就是x的一份拷贝。

int main()
{
	int x = 10;
	auto a = &x;//根据右边推出,a是一个指针类型
	auto* b = &x;//右边必须是一个地址,因为前面加了*
	auto& c = x;//引用必须要加&
}

🪆在同一行定义多个变量
 当在同一行声明多个变量的时候,这些变量必须是相同的类型,否则编译器会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

int main()
{
	auto a = 10, b = 30;
	auto c = 60, d = 1.1;//该行编译失败,c和d的初始化类型不同
}

2.3 不能使用auto的场景

  • auto不能作为函数的参数
//错误,编译器无法对x的实际类型进行推导
void Text(auto x)
{}
  • ·auto不能直接用来声明数组
void Text()
{
	//auto arr[] = { 1, 2, 3 };//错误写法,请勿模仿
	int arr[] = {1, 2, 3}//这才是正确写法
}

小Tips:auto在实际中常被用在:基于范围的for循环中、还有lambda表达式中、其次就是一些非常非常长的类型,也会用auto进行替换。

三、基于范围的for循环

🪆C++98中遍历一个数组:

void TestFor()
{
	int array[] = { 1, 2, 3, 4, 5 };
	for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)//通过下标访问
     	array[i] *= 2;
	for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)//通过指针访问
     	cout << *p << endl;
}

🪆C++98中遍历一个数组:
 对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还容易犯错误。因此C++11中引入了基于范围for循环。for循环后的括号由冒号“ : ”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围

void TestFor()
{
	int array[] = { 1, 2, 3, 4, 5 };
	for(auto& e : array)//加引用可以对后面的值修改
     	e *= 2;
	for(auto e : array)
     	cout << e << " ";
	return 0;
}

3.1 范围for的使用条件

  • for循环迭代的范围必须是确定的
  • 迭代的对象要实现++和==的操作

对数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end方法,begin和end就是for循环的迭代范围。范围for本质上是迭代器,支持迭代器就支持范围for

void Text(int arr[])//arr本质上只是一个地址,没有范围
{
	for (auto a : arr)//错误
	{
		cout << a << endl;
	}
}

四、指针空值nullptr

 良好的编程习惯要求我们,在声明一个变量时最好给该变量一个合适的初始值,否则可能出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们一般会把它置空。
🪆回顾NULL:

void f(int)
{
	cout << "f(int)" << endl;
}
void f(int*)
{
	cout << "f(int*)" << endl;
}
int main()
{
	f(0);
	f(NULL);
	return 0;
}

上述代码的本意是:希望通过f(NULL);去调用void f(int*),但是通过执行结果可以看出,f(NULL);调用的是void f(int)。这是因为NULL被定义成了0,且C++98中规定,字面常量0,既可以是一个整型数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成一个整型常量,如果要将其按照指针的方式来使用,必须对其进行强制类型转换(void*)0

🪆认识nullptr:
nullptr用来表示指针空值,因为nullptr是C++11作为新关键字引入的,所以在使用的时候不需要包头文件。C++11中,sizeof(nullptr)sizeof((void*)0)所占字节数相同。

int main()
{
	cout << sizeof(nullptr) << endl;
	cout << sizeof((void*)0) << endl;
	return 0;
}

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

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

相关文章

ES6标准---【二】【学习ES6看这一篇就够了!!】

目录 ES6以往文章 ES6新增字符串方法&#xff1a; includes()、startsWith()、endsWith() repeat() padStart()、padEnd() 常见用途 为数值补全指定位数 提示字符串格式 trimStart()、trimEnd() String.raw() ES6以往文章 ES6标准-【一】【学习ES6看这一篇就够了&a…

开关电源综合测试平台自动生成报告,智能分析电源测试参数

在电源模块的检测过程中&#xff0c;数据的准确性和分析效率至关重要&#xff0c;开关电源综合测试平台的数据报告和数据分析功能为企业的电源测试带来了便利。 NSAT-8000开关电源综合测试平台是集自动化测试与数据收集分析于一体的综合测试软件&#xff0c;打破了传统测试系统…

【组件】WEB前端-富文本编辑器组件推荐 在线编辑器 Word

【组件】WEB前端-富文本编辑器组件推荐 在线编辑器 Word canvas-editor 基于canvas/svg的富文本编辑器 canvas-editor | rich text editor by canvas/svgrich text editor by canvas/svghttps://hufe.club/canvas-editor-docs/ canvas-editor 基于canvas/svg的富文本编辑器 开…

文案改写工具有哪些?5款智能改写工具迅速提升文案品质

在信息爆炸的时代&#xff0c;优秀的文案如同黄金&#xff0c;能瞬间抓住消费者的眼球。然而&#xff0c;创作出独具匠心的文案并非易事&#xff0c;尤其是当需要不断改写以保持文案内容新鲜感时。那么&#xff0c;文案改写工具有哪些是能帮助我们事半功倍呢&#xff1f;以下5款…

Goby 漏洞发布|(CVE-2024-45195)Apache OFBiz /viewdatafile 代码执行漏洞【已复现】

漏洞名称&#xff1a;Apache OFBiz /viewdatafile 代码执行漏洞&#xff08;CVE-2024-45195&#xff09; English Name&#xff1a;Apache OFBiz /viewdatafile Code Execution Vulnerability(CVE-2024-45195) CVSS core: 8.0 漏洞描述&#xff1a; Apache OFBiz是一个开源…

--数据库--

制作工人薪资管理系统 #include <myhead.h> #include <sqlite3.h> typedef struct {int gh;char name[20];double salary; }Worker;int do_insert(sqlite3 *ppdb) {Worker work;printf("请输入插入的工号&#xff1a;");scanf("%d",&work.…

基于Verilog HDL的FPGA设计基础

第一章 Verilog数字集成电路设计方法概述 HDL(Hardware Description Language)----硬件描述语言 EDA(Electronic Design Automation)----电子设计自动化 VLSI(Very Large Scale Integrated)----超大规模集成电路 ASIC(Application Specific Integrated Circuit)----专用集成电路…

坚守官网,深挖没有错;积极转型也没错,就怕10年前经验用在现在

如今官网建设领域哀嚎一片&#xff0c;出现三种应对策略。 其一&#xff1a;坚守官网&#xff0c;深挖下去&#xff0c;做出高大上&#xff0c;精美炫酷和实效网站&#xff0c;路子很对。 其二&#xff1a;积极寻求转型&#xff0c;客户需要啥就做啥&#xff0c;比如搞小程序…

Vue3可编辑表格插件

插件亮点&#xff1a; 通过可自定义单元格内容。可控的状态控制&#xff0c;例如只读、禁止编辑行等配置。可控的状态交互&#xff0c;例如框选单元格、框选行等配置。可控的推拽顺序&#xff0c;例如拖拽行、推拽列。方便的单元格数据验证配置。方便的快捷右键菜单&#xff0c…

std::map 合并

目录 示例 效果 采用insert函数实现两个map的合并。使用方法&#xff1a; map1.insert(map2) 假如map2的某些键也出现在map1里面&#xff0c;则map1中重复的键值对不变&#xff0c;map2中重复的键值对无法覆盖map1。 示例 #include <map> #include <iostream>…

USB转百兆网卡芯片CH397在多平台下使用说明

简介 CH397是一款USB2.0高速转以太网芯片&#xff0c;支持10M/100M网络的以太网MACPHY&#xff0c;内置青稞RISC-V 处理器、符合IEEE802.3 和IEEE802.3az-2010 协议规范。支持Windows/ Linux /macOS /iOS /Android 等多平台各系统&#xff0c;适配各类台式电脑、笔记本电脑、平…

【Nacos】报错之服务实例类型不允许改变

在使用Nacos配置服务的实例类型的时候&#xff0c;对服务的实例类型进行修改。 之前的非临时实例&#xff0c;修改为临时实例后&#xff0c;报错&#xff1a; com.alibaba.nacos.api.exception.NacosException: errCode: 400, errMsg: Current service DEFAULT_GROUPproduct-…

洛谷 P1039 [NOIP2003 提高组] 侦探推理

题目来源于&#xff1a;洛谷 原题点这里 题目本质&#xff1a;模拟&#xff0c;字符串&#xff0c;差分&#xff0c;模拟 题目思路&#xff1a; 记录每一句话是谁说的以及这句话的内容&#xff0c;可以用map存人名对应的下标&#xff0c;我们枚举每一个人i&#xff0c;假设i…

数据结构与算法1: 链表

基础知识 链表可以被想象为一系列的节点&#xff0c;每个节点至少有一个指针指向下一个节点&#xff0c;在最后一个节点&#xff0c;用null pointer来表示链表的结束。 链表的创建速度通常很快&#xff0c;在表头和表尾的插入也很快&#xff08;O(1)&#xff09;&#xff0c;…

2024年T电梯修理证模拟考试题库及T电梯修理理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年T电梯修理证模拟考试题库及T电梯修理理论考试试题是由安全生产模拟考试一点通提供&#xff0c;T电梯修理证模拟考试题库是根据T电梯修理最新版教材&#xff0c;T电梯修理大纲整理而成&#xff08;含2024年T电梯…

餐饮酒店旅游服务网站整站模板打包下载

餐饮酒店旅游服务网站整站模板打包下载 餐饮酒店旅游服务网站整站模板打包下载 餐饮酒店旅游服务网站整站模板打包下载 餐饮酒店旅游服务网站整站模板打包下载 餐饮酒店旅游服务网站整站模板打包下载 响应式酒店旅租网站模板_餐饮酒店旅游服务类网站整站打包下载.zip 农家…

怎么能实现VIN码充电吗?针对一个单一的VIN码,设置不同的服务费这种计费模式

为了实现VIN码充电并针对单一VIN码设置不同的服务费这种计费模式&#xff0c;需深入了解VIN码充电的实现过程及技术细节。VIN码充电是一种基于车辆识别号码&#xff08;VIN&#xff09;进行充电和计费的方法&#xff0c;适用于新能源汽车的充电桩。具体分析如下&#xff1a; V…

828华为云征文|华为云Flexus X实例docker部署mediacms,功能齐全的现代化开源视频和媒体CMS

828华为云征文&#xff5c;华为云Flexus X实例docker部署mediacms&#xff0c;功能齐全的现代化开源视频和媒体CMS 华为云最近正在举办828 B2B企业节&#xff0c;Flexus X实例的促销力度非常大&#xff0c;特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、…

时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR

时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR 文章目录 一、基本原理二、实验结果三、核心代码四、代码获取五、总结 时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR 一、…

CMU 10423 Generative AI:lec4(必读:Sliding Window Attention,RoPE, GQA)

lec4有4篇必读文献分别是&#xff1a;Sliding Window Attention&#xff0c;RoPE&#xff0c;GQA&#xff0c;以及花书的CNN第9.1~9.3节。前3个详细研究了一下&#xff0c;如下&#xff1a; 文章目录 1 Sliding Window Attention&#xff08;2020&#xff09;1.1 概览1.2 个人总…