【C++】踏上C++学习之旅(五):auto、范围for以及nullptr的精彩时刻(C++11)

文章目录

  • 前言
  • 1. auto关键字(C++11)
    • 1.1 为什么要有auto关键字
    • 1.2 auto关键字的使用方式
    • 1.3 auto的使用细则
    • 1.4 auto不能推导的场景
  • 2. 基于范围的for循环(C++11)
    • 2.1 范围for的语法
    • 2.2 范围for的使用条件
  • 3. 指针空值nullptr(C++11)
    • 3.1 为什么会有nullptr这个关键字?

图片

前言

本文我了解一下C++11新特性的auto、范围for以及nullptr给我们的编程带来了什么样的好处,以及我们在特定的场景该如何使用它们。

温馨提示:本文所讲到的C++11(2011年)和C++98(1998年)均为C++编译器的版本。

OK,让我们一起探索这些auto、范围for以及nullptr背后的秘密。

哈哈哈


1. auto关键字(C++11)

这里需要说明的一点是,在C++98就已经有auto这个关键字了。不过在C++98的做法中,它将auto关键字视作一个存储类型的指示符。换句话说,只要是在C++98中使用auto关键字定义的变量就是一个具有自动存储器功能的局部变量 – 待补充

1.1 为什么要有auto关键字

这就要往类型别名的方向去思考这个问题。

想一个现象,随着我们越学到后面,代码就会变得愈加复杂,伴随的是声明类型的长度也会增加,这个就会导致两个问题:

  1. 类型难以拼写;
  2. 类型含义不明确导致出错。

这么说可能有点干巴,下面我来展示一段代码(这个是大家以后学习C++要用到的):

#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;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>std::map<std::string, std::string>::iterator,这两个类型够长吧,即使你能记得住,如果有很多地方都要定义的话,我估计你的键盘可能会敲冒烟。

那有的人就会这么想,那我可以用typedef来给这些长的类型起一个别名,比如下面这样:

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

这个方法确实是可以的,但是你能确保在庞大的代码量面前,你能十分的明确Map这个类型所代表的具体含义吗?本人觉得这是一件很难的事,另外用typedef关键字,还有个重要的细节:

#include<iostream>
using namespace std;typedef int* int_ptr;
int main()
{int num1 = 66,num2 = 88;//写法1:int_ptr a = &num1 , b = &num2;//写法2:int_ptr a = &num1 , *b = &num2;//以上两种写法那个是正确的?
}

答案:写法一是正确的。

#include<iostream>
using namespace std;int main()
{int num1 = 66,num2 = 88;//写法1:int* a = &num1 , b = &num2;//写法2:int* a = &num1 , *b = &num2;//以上两种写法那个是正确的?
}

答案:写法二是正确的。

如果你上面两道题目做对了一道的话,那我想auto关键字就很适合你使用了!

1.2 auto关键字的使用方式

🍉auto 变量名 = 值;
🍇编译器在编译的过程看到auto就会根据赋值符号右边的表达式推导出出变量名的类型!

#include<iostream>
using namespace std;int main()
{auto a = 's';auto b = 66;auto c = 520.13f;auto d = 0.1314;//auto也可以推导出表达式的值的数据类型auto tmp = b + d;//我们可以用typdeid(变量名).name()cout << typeid(a).name() << endl;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;cout << typeid(d).name() << endl;cout << typeid(tmp).name() << endl;return 0;
}

测试结果

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

1.3 auto的使用细则

  1. auto与指针和引用结合起来使用
    用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&。
	//auto*和auto用来代表指针类型都是一样的,但是如果我们要用引用的话,就必须在auto后面加上&。int a = 10;int b = 66;int c = 88;auto* pa = &a;auto pb = &b;auto& ic = c;cout << typeid(pa).name() << endl;cout << typeid(pb).name() << endl;cout << typeid(ic).name() << endl;return 0;

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

void TestAuto()
{auto a = 10, b = 20;auto c = 3, d = 4.0; //该行代码会编译失败,因为c和d的初始表达式类型不同
}

1.4 auto不能推导的场景

  1. auto不能作为函数的形参
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
  1. auto不能直接声明数组
void TestAuto()
{int a[] = {1,2,3};auto b[] = {456}; //会报错
}

好了,到这里auto关键字的用法也了解的差不多了。那么接下来我们再来看看C++的一个"语法糖"——“范围for”!
hahah


2. 基于范围的for循环(C++11)

2.1 范围for的语法

我们在C++98中如果要遍历一个数组,是这样做的:

void TestFor()
{int arr[] = {1,2,3,4,5,6,7,8,9,0};for(int i = 0 ; i < sizeof(arr) / sizeof(int); ++i){cout<< arr[i] << ' ';}cout << endl;for(int* p = arr; p < arr + sizeof(arr)/sizeof(int); p++){cout << *p << ' ';}cout << endl;}

==对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。==因此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;
}

注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。

2.2 范围for的使用条件

  1. for循环迭代的范围必须是确定的
    对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。

注意:以下代码就有问题,因为for的范围不确定

void TestFor(int array[])
{for(auto& e : array)cout<< e <<endl;
}
  1. 迭代的对象要实现++和==的操作。(关于迭代器这个问题,以后会讲,现在提一下,没办法讲清楚,现在大家了解一下就可以了)

范围for比较简单,只要求会用就可以了。那接下来再来讲讲另一个关键字"nullptr"!


3. 指针空值nullptr(C++11)

3.1 为什么会有nullptr这个关键字?

有的读者可能会诧异,不是说C++兼容C语言吗?那我们就直接用C语言的NULL作为来表示指针空值就行了啊,为什么C++还要单独再弄一个nullptr关键字出来呢?

我们可以查看C++下的NULL:
在main函数中敲一个NULL,之后点击鼠标右键,然后点击"转到定义"。
步骤一
NULL定义的地方:
大
可以看到的是NULL在cpp文件中是字面常量0

如果我们要是在C++中用NULL,可能会遇到一些麻烦,比如下面的这段代码:

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

图

程序本意是想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的初衷相悖。

在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

注意:

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

好了,到这里,你感受到了auto、范围for和nullptr的魅力了吗?

如果觉得本文写的不错的话,麻烦给偶点个赞吧!!!

hahaha

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot2.x使用SSE方式代理或者转发其他流式接口

文章目录 1.需求描述2.代码2.1.示例controller2.2.示例service2.3.示例impl 3.测试 1.需求描述 使用SSE的方式主要还是要跟前端建立一个EventSource的链接&#xff0c;有了这个连接&#xff0c;然后往通道里写入数据流&#xff0c;前端自然会拿到流式数据&#xff0c;写啥拿啥…

“高效开发之路:用Spring MVC构建健壮的企业级应用”

一、SpringMVC框架概念&#xff1a; &#xff08;一&#xff09;概述 SpringMVC是Spring框架的一个模块&#xff0c;Spring和SpringMVC无需中间整合层整合。该模块是一个基于MVC的web框架。 作用&#xff1a;只要需要前后端通信&#xff0c;就需要springMVC帮我完成&#xff…

论文阅读笔记:Activating More Pixels in Image Super-Resolution Transformer

论文阅读笔记&#xff1a;Activating More Pixels in Image Super-Resolution Transformer 1 背景1.1 问题1.2 提出的方法 2 创新点3 方法4 模块4.1 混合注意力模块&#xff08;HAB&#xff09;4.2 重叠交叉注意力模块&#xff08;OCAB&#xff09;4.3 同任务预训练 5 效果5.1 …

制作gif动图并穿插到CSDN文章中

一、下载LICEcap软件 安装包放在文章末尾 二、双击运行 会出现一个透明框&#xff0c;可以通过左下角的Size来修改画布大小&#xff0c;也可以直接拖动来调整 把透明框拖至自己想放置的位置 点击record进行录制&#xff0c;点击stop暂停&#xff0c;录制完成后给自己的gif图…

新160个crackme - 093-kesan

运行分析 需破解用户名和注册码 PE分析 Delphi程序&#xff0c;32位&#xff0c;无壳 静态分析&动态调试 ida找不到字符串&#xff0c;根据Delphi程序逻辑&#xff0c;双击进入cls_Unit1_TForm1查找 向下翻找后发现4个事件&#xff0c;逐个分析 动调_TForm1_Edit1Change函数…

自己开发得期货资管模拟软件演示1.0.15版仅供学习

期货资管模拟软件演示1.0.15版仅供学习——C技术栈知识分享 本文将以期货资管模拟软件演示1.0.15版为例&#xff0c;分享其基于C技术栈的框架知识。 一、C技术栈在期货交易软件开发中的应用 C作为一种高性能的编程语言&#xff0c;以其强大的内存管理能力和高效的执行速度&a…

详解:字符串常量池

字符串常量池是Java运行时环境&#xff08;JRE&#xff09;的一部分&#xff0c;它用于存储字符串字面量。字符串字面量是源代码中直接用双引号括起来的字符串&#xff0c;例如"hello"。在Java中&#xff0c;字符串是不可变的&#xff0c;这意味着一旦创建了一个字符…

三次样条插值算法及推导过程

目录 1、定义 2、已知条件求解 3、具体推导 4、matlab案例 5、案例结果 6、matlab仿真 1、定义 给定 n 1 n1 n1个数据点&#xff0c;共有 n n n个区间&#xff0c;三次样条方程 S ( n ) S(n) S(n)满足以下条件&#xff1a;在每个分段区间内 ( x i , x i 1 ) (x_i,x_{i1}) (…

[数据结构从小白到大牛]第五篇:3分钟带你吃透双链表并用C语言模拟实现

目录 1->前言 2->链表的概念和结构 2.1链表概念 2.2->带头双向循环链表结构 3->模拟实现带头双向循环链表 3.1定义链表结点 struct ListNode 3.2创建链表结点 CreateLTNode 函数 3.3链表初始化函数 ListInit函数 3.4链表打印函数 ListPrint函数 3.5链表…

Rancher的安装

1. 概览 1.1 用户界面优势 Rancher 提供了一个直观的图形用户界面&#xff08;GUI&#xff09;。对于不熟悉 Kubernetes 复杂的命令行操作&#xff08;如使用kubectl&#xff09;的用户来说&#xff0c;通过 Rancher 的界面可以方便地进行资源管理。例如&#xff0c;用户可以在…

【办公类-04-04】华为助手导出照片视频分类(根据图片、视频的文件名日期导入“年-月-日”文件夹中,并转移到“年-月”文件中整理、转移到“年”文件夹中整理)

背景需求 最近带班&#xff0c;没有时间整理照片&#xff0c;偶尔导一次&#xff0c;几个月的照片。发现用电脑版“华为手机助手“中的WLAN连接”与华为手机的“华为手机助手”连接&#xff0c;速度更快、更稳定&#xff0c;不会出现数据线连接时碰碰就断网的问题 1、先打开电…

CDGP|企业数据治理流程全解析

在当今信息化时代&#xff0c;数据已成为企业最重要的资产之一。为了充分发挥数据的价值&#xff0c;企业需要对数据进行全面、系统的治理。企业数据治理流程是一套确保数据质量、安全性和合规性的规范化流程&#xff0c;涵盖了从数据采集到销毁的全过程。本文将详细介绍一般企…

学习threejs,将多个网格合并成一个网格

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.Geometry 几何体1.2 …

Linux 线程控制

一. 线程互斥 1.1 线程互斥相关概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源。临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区。互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入临界区&…

Centos安装ZooKeeper教程(单机版)

本章教程介绍,如何在Centos7中,安装ZooKeeper 3.9.3版本。 一、什么是ZooKeeper ? Apache ZooKeeper 是一个分布式协调服务,用于大型分布式系统中的管理和协调。它为分布式应用提供了一个高性能的通信框架,简化了开发人员在构建复杂分布式系统的任务。ZooKeeper 能够解决一…

企业CRM管理系统PHP源码/PHP客户关系CRM客户管理系统源码

系统功能实现 1、 公海管理:公海类型、客户公海。 2、 线索管理:我的线索、线索列表、线索状态、线索来源。 3、 客户管理:我的客户、客户列表、成交客户、行业类别、预查、地区列表、客户状态、客户级别。 4、 业绩订单:订单列表、我的订单。 5、 系统设置:系统设置…

设置JAVA以适配华为2288HV2服务器的KVM控制台

华为2288HV2服务器比较老旧了&#xff0c;其管理控制台登录java配置比较麻烦&#xff0c;华为的ibmc_kvm_client_windows客户端测试了几个版本&#xff0c;连接控制台也有问题&#xff0c;最终安装JDK解决。 一、测试环境 主机为WindowsServer2012R2,64位系统 二、Java软件包…

10大软件使用感受分享,数据恢复的得力助手!!

在找数据恢复软件&#xff1f;&#xff01;是不是存在误删重要文件或遭遇硬盘故障&#xff0c;想要找回丢失的数据&#xff1f;别担心&#xff0c;今天我就来给大家分享10款我亲自使用过的数据恢复软件&#xff0c;分别给你说说它们各自的优缺点&#xff0c;希望能帮你们在数据…

一周模电速成(3) 超详细!入门小白速成!!!

目录 稳压二极管 整流二极管 晶体三极管 三极管结构图 三极管的特点 1、如何让它工作在放大状态呢 2、如何工作在截止状态呢&#xff1f; 3、如何让三极管工作在饱和状态呢&#xff1f; 在电路中要如何实现呢&#xff1f;工作在各个状态有什么特点呢&#xff1f; 截止…