c++阶梯之auto关键字与范围for

auto关键字(c++11)

1. auto关键字的诞生背景

随着程序的逐渐复杂,程序代码中用到的类型也越来越复杂。譬如:

类型难以拼写;含义不明确容易出错。

比如下面一段代码:

#include <string>
#include <map>
int main()
{
std::map<std::string, std::string> m{ { "apple", "苹果" }, { "orange",
"橙子" },
{"pear","梨"} };
std::map<std::string, std::string>::iterator it = m.begin();
while (it != m.end())
{
//....
}
return 0;
}

 std::map<std::string, std::string>::iterator 是一个类型,但是该类型太长了,容
易写错并且耗费时间成本。有人会说,我们学过typedef,给他起个别名。

但typedef也会遇到新的问题 :

typedef char* pstring;
int main()
{
const pstring p1; // 编译成功还是失败?
const pstring* p2; // 编译成功还是失败?
return 0;
}

在编程时,常常需要把表达式的值赋值给变量,这就要求在声明变量的时候清楚地知道表达式的类型。然而有时候要做到这点并非那么容易,因此C++11给auto赋予了新的含义。 

2. auto简介

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

char TestAuto()
{
	char m='*';
	return m;
}
int main()
{
	int a = 10;
	auto b = a;
	auto c = 't';
	auto d = TestAuto();

	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;

	return 0;

}

 

注意

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

3. auto的使用细则

3.1 auto同指针与引用结合使用 

用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须
加&

int main()
{
	int a = 10;
	auto* b = &a;
	auto c = &b;
	auto& d= a;

	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;

	*b = 30;
	cout << a << endl;
	**c = 50;
	cout << a << endl;
	d = 80;
	cout << a << endl;
	return 0;
}

 

3.2 在同一行定义多个变量

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

 

3.3 auto不能推导的场景 

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

 

因为此处编译器无法对a的实际类型进行推导。

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

为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法。

基于范围的for循环(c++11) 

1. 范围for的语法

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因
此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范
围内用于迭代的变量,第二部分则表示被迭代的范围
int main()
{
	int arr[] = { 1,2,3,4,5 };
	for (auto& e : arr)
	{
		e *= 2;//如果要修改内容,需要引用
	}
	for (auto e : arr)
	{
		cout << e << " ";
	}

	char str[] = "abcde";
	for (auto a : str)
	{
		cout << a << " ";
	}
	return 0;
}

注意:与普通循环类似,可以使用continue跳出本次循环,也可以使用break退出循环。 

 2. 范围for的使用条件

 for循环迭代的范围必须是确定的

对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供
begin和end的方法,begin和end就是for循环迭代的范围。
注意:以下代码就有问题,因为for的范围不确定 

void test(int arr[])
{
	for (auto e : arr)
	{
		cout << e << "";
	}
}

int main()
{
	int arr[10] = { 1,2,3,4,5 };
	test(arr);
	return 0;
}

 

指针空值nullptr(c++11) 

C++98中的指针空值 

在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化: 

int main()
{
	int a = 0;
	int* p = NULL;
	return 0;
}

我们来看下面这段代码

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

在我们看来,NULL是空指针,因此应该调用两次test(int* p),但其实不然,我们来看看结果。

 这是为什么呢?

我们可以看到,NULL实际上是一个宏,可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦。

注意

1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入
的。
2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

结语

接下来正式进入c++的难点类与对象,共勉! 

 

 

 

 

 


 

 



 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(学习日记)2024.02.01:引用变量 / 默认实参 / 一元作用域运算符 / 函数重载

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

踩坑STM32CubeMX生成Makefile工程无法使用printf(“%f“)

过去一年偶有接触STM32开发时都是使用STM32CubeMX生成Makefile的工程&#xff0c;具体开发环境见配置Clion用于STM32开发&#xff08;Makefile&#xff09;&#xff0c;但没想到今天在使用printf打印输出浮点数时无法正常输出&#xff0c;不仅printf无法使用&#xff0c;其他涉…

MongoDB从入门到实战之MongoDB快速入门

前言 上一章节主要概述了MongoDB的优劣势、应用场景和发展史。这一章节将快速的概述一下MongoDB的基本概念&#xff0c;带领大家快速入门MongoDB这个文档型的NoSQL数据库。 MongoDB从入门到实战的相关教程 MongoDB从入门到实战之MongoDB简介&#x1f449; MongoDB从入门到实战…

白皮书发布,石油石化数字孪生加速

近日&#xff0c;《数字石化 孪生智造——石油石化数字孪生白皮书》发布。白皮书聚焦石油石化行业发展机遇&#xff0c;剖析数字孪生技术在行业中的案例实践与应用场景&#xff0c;展望石油石化企业未来孪生发展新态势。 当前&#xff0c;国家大力推动减污降碳协同增效&#x…

【IM】长连接网关设计探索(一)

目录 1.长连接网关的必要性2. 设计目标2.1 技术挑战2.2 技术目标 3. 方案选型3.1 网关IP地址的选择3.1.1 使用httpDNS服务3.1.2 自建http server作为IP config server3.1.3 最佳方案 3.2 高并发收发设计3.2.1 C10K问题3.2.2 方案探索双协程监听channel实现全双工 一个定时器 1…

Unity学习之Unity核心(一)2D相关

文章目录 1. 前言2 图片导入概述3 图片设置的六大部分3.1 纹理类型3.1.1 Default3.1.2 Normal Map 法线贴图格式3.1.3 Editor GUI and Legacy GUI3.1.4 Sprite3.1.5 Cursor 自定义光标3.1.6 Cookie 光源剪影格式3.1.7 LightMap光照贴图格式3.1.8 Single Channel 纹理只需要单通…

【新书推荐】5.1节 16位汇编语言学习环境

第五章 16位汇编学习环境 16位汇编语言的学习环境是建立在8086计算机的基础上的&#xff0c;我将借助于DosBox虚拟机来实现16位汇编语言学习环境的搭建。 5.1节 16位汇编语言学习环境 本节内容&#xff1a;16位汇编学习环境的搭建。 ■汇编语言程序设计编程调试过程&#xff1…

Vulnhub billu b0x

0x01 环境搭建 1. 从官方下载靶机环境&#xff0c;解压到本地&#xff0c;双击OVF文件直接导入到vmware虚拟机里面。2. 将虚拟机的网络适配器调成NAT模式&#xff0c;然后开机即可进行操作了。 0x02 主机发现 nmap -sn 192.168.2.0/24 成功获取靶机IP为192.168.2.129。 0x0…

sqli.labs靶场(23关到28a关)

23、第二十三关 id1单引号闭合 找位置1 and 12 union select 1,2,3 爆库&#xff1a;1 and 12 union select 1,2,database() 爆表名&#xff1a;1 and 12 union select 1,2,group_concat(table_name) from information_schema.tables where table_schemasecurity 爆字段&#…

【大数据】Flink SQL 语法篇(二):WITH、SELECT WHERE、SELECT DISTINCT

Flink SQL 语法篇&#xff08;二&#xff09; 1.WITH 子句2.SELECT & WHERE 子句3.SELECT DISTINCT 子句 1.WITH 子句 应用场景&#xff08;支持 Batch / Streaming&#xff09;&#xff1a;With 语句和离线 Hive SQL With 语句一样的&#xff0c;语法糖 1&#xff0c;使用…

谷歌seo搜索引擎优化需要做什么?

当你要做谷歌seo&#xff0c;经手一个你之前没有接触过的网站&#xff0c;你首先要做的就是分析网站当前的流量数据&#xff0c;如果是新站自然不需要这一步&#xff0c;不过数据分析依旧是件很重要的事情&#xff0c;做seo不懂得分析数据相当于白做 再来就是你要了解网站所在的…

卸载Ubuntu双系统

卸载Ubuntu双系统 我们卸载Ubuntu双系统&#xff0c;可能出于以下原因&#xff1a; 1、Ubuntu系统内核损坏无法正常进入 2、Ubuntu系统分配空间不足&#xff0c;直接扩区较为复杂 3、以后不再使用Ubuntu&#xff0c;清理留出空间 123无论出于哪种原因&#xff0c;我们都是要…

柔性电流探头方向判断有哪些方法?干货分享!

柔性电流探头方向判断的方法干货分享&#xff01;从理论到实践&#xff0c;助您成为专业人士&#xff01;干货收藏&#xff0c;快看起来吧&#xff01;      柔性电流探头方向判断一直是电力行业测试中的关键问题之一&#xff0c;确切地判断电流方向对于测试电力系统的稳定…

【GitHub项目推荐--一个由OpenAI提供支持的聊天机器人和虚拟助手的构建平台】【转载】

Botpress Botpress是一个开源项目&#xff0c;它提供了一个平台&#xff0c;用于构建、部署和管理基于人工智能的聊天机器人和虚拟助手 github地址&#xff1a; https://github.com/botpress/botpress Botpress的介绍 Botpress是一个开源项目&#xff0c;它提供了一个平台&…

ROS2 Humble学习笔记 (2)

本文发表于个人的github pages。因csdn本身显示插件和转载过程中导致显示不太友好。建议大家阅读原文。想查看完整内容&#xff0c;请移步到ROS2 Humble学习笔记2。 本文篇幅较长&#xff0c;可抽空按照章节阅读。本文只作为对入门教程的一种浮现和提升。 一、前言 在上一篇…

Spring框架——主流框架

文章目录 Spring(轻量级容器框架)Spring 学习的核心内容-一图胜千言IOC 控制反转 的开发模式Spring快速入门Spring容器剖析手动开发- 简单的 Spring 基于 XML 配置的程序课堂练习 Spring 管理 Bean-IOCSpring 配置/管理 bean 介绍Bean 管理包括两方面: Bean 配置方式基于 xml 文…

2023年上-未来几年我要做什么

1月份&#xff0c;离职。 2月份&#xff0c;春节休假回来&#xff0c;中旬去参加了一个月的瑜伽培训&#xff0c;学会了倒立、鹤蝉。。。。 3月份&#xff0c;瑜伽培训结束&#xff0c;开始收拾房子&#xff0c;并调研各类项目。 4月份&#xff0c;参与了朋友的区块链项目 …

echarts step line

https://ppchart.com/#/ <template><div class"c-box" ref"jsEchart"></div> </template><script> import * as $echarts from echarts // 事件处理函数 export default {props: {// 需要传递的数据data: {type: Array,defa…

Day06-Linux下目录命令讲解及重要文件讲解

Day06-Linux下目录命令讲解及重要文件讲解 1. Linux目录文件1.1 Linux系统目录结构介绍1.1.1 Linux与Windows目录结构对比 1.2 重要的Linux配置文件介绍1.2.1 /etc系统初始化及设置相关重要文件1.2.2 /usr目录的重要知识介绍------应用程序目录1.2.3 /var目录下的路径知识-----…

thinkphp项目之composer快速安装使用

引言 由于项目的需求&#xff0c;thinkphp项目使用到composer。网上搜索有一堆的教程使用&#xff0c;根据自己的需要摸索了下。 步骤 1. 安装phpstudy v8&#xff0c;这个经常用的运行环境&#xff0c;方便好多开发者。安装教程一步一步到最后就行。 2. 安装composer组件&a…