【C++关键字】auto以及指针空值nullpr


📙 作者简介 :RO-BERRY
📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持


请添加图片描述


目录

  • 前言
  • 1.类型别名思考
  • 2.auto简介
  • 3.auto的使用细则
    • 1. auto与指针和引用结合起来使用
    • 2. 在同一行定义多个变量
    • 3.auto不能推导的场景
  • 4.基于范围的for循环(C++11)
    • 1. 范围for的语法
    • 2.范围for的使用条件
  • 5.指针空值nullptr
    • 1 C++98中的指针空值


前言

C++11新增了一个工具,让编译器能够根据初始值的类型推断变量的类型。为此,他重新定义了auto的含义。auto是一个C语言关键字,但很少使用。在初始化声明中,如果使用关键字auto,而不指定变量的类型,编译器将把变量的类型设置成与初始值相同

auto x = 100;     //X is int
auto y = 1.5;     //y is double
auto z = 1.3e12L  //z is long double

然而,自动推断类型并非为这种简单情况而设计的;事实上,如果将其用于这种简单情形,甚至可能会让您误入歧途。例如,假设您要将x、y、z都指定为double类型,并编写了如下代码:

auto x = 0.0      //x为double类型,因为0.0是double
double y = 0      //0被强制转换为double类型
auto z =0         //z为int类型,因为0是int

显示地声明类型时,将变量初始化为0(而不是0.0)不会导致任何问题,但采用自动类型推断时,这却会导致问题


1.类型别名思考

随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在:

  1. 类型难于拼写
  2. 含义不明确导致容易出错

例如如下这段代码:

#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给类型取别名,比如:

#include <string>
#include <map>
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;
}

使用typedef给类型取别名确实可以简化代码,但是typedef有会遇到新的难题:

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

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


2.auto简介

在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的
是一直没有人去使用它,大家可思考下为什么?
C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一
个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

注意

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


3.auto的使用细则

1. auto与指针和引用结合起来使用

用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须
加&
在这里插入图片描述

2. 在同一行定义多个变量

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

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

3.auto不能推导的场景

  1. auto不能作为函数的参数
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
  1. auto不能直接用来声明数组
void TestAuto()
{int a[] = {1,2,3};auto b[] = {456};
}
  1. 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法
  2. auto在实际中最常见的优势用法就是跟以后会讲到的C++11提供的新式for循环,还有
    lambda表达式等进行配合使用。

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

1. 范围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++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.范围for的使用条件

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

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

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

5.指针空值nullptr

1 C++98中的指针空值

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

void TestPtr()
{int* p1 = NULL;int* p2 = 0;// ……
}

NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:

#ifndef NULL
#ifdef __cplusplus
#define NULL   0
#else
#define NULL   ((void *)0)
#endif
#endif

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

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

程序本意是想通过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。

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

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

相关文章

快速排序详解!c语言

目录 快速排序是什么&#xff1f; 快速排序的三种方法&#xff01; 快速排序的优化 1.hore法&#xff08;初代目&#xff09; hore法的源码 源码解析 2.挖坑法&#xff08;常用&#xff09;&#xff01;&#xff01;&#xff01;&#xff01; 挖坑法源码 3.前后指针法…

springboot快鞋屋系统-计算机毕业设计源码06912

摘 要 如今&#xff0c;人们的消费水平和购物能力都大大提升&#xff0c;加上互联网技术日新月异的发展&#xff0c;电子商务这种新兴的商业模式&#xff0c;在短短几年里已经开始融入中国社会&#xff0c;成为家哈户晓的热门话题&#xff0c;在网上购物已经成为一种潮流&#…

键盘输入4个数,从小到大排序

题目 键盘输入4个整数&#xff0c;从小到大排序 思路 代码 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h>//键盘输入4个整数&#xff0c;从小到大排序 int main() {int n1, n2, n3, n4;scanf_s("%d %d %d %d", &n1, &n2, &n3, &n4);…

基于Java开发的个人视频网站的搭建与实现[附源码]

基于Java开发的个人视频网站的搭建与实现[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &am…

网工内推 | 外企网工、售前,最高15K*13薪,厂商认证优先

01 广州群欣软管有限公司 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1、负责公司计算机及办公设备的软、硬件日常维护&#xff1b; 2、负责公司erp系统、监控系统及网站的管理维护&#xff1b; 3、负责根据公司发展战略方向及业务规划&#xff0c;制定公司信息化的…

ST32——点亮第一盏灯

环境搭建 项目模板搭建 main函数 电路图 代码示例 #include "gd32f4xx.h" #include "systick.h" #include <stdio.h> #include "main.h"/** LED硬件对应关系 LED1 PE3 LED2 PD7 LED3 PG3 LED4 PA5点亮LED1 **/int main(void) {systick_…

【Linux】---Linux下基本指令(2)

目录 一、指令详细介绍1.1 cat 指令1.2 echo 指令1.3 more 指令1.4 less 指令1.5 head 指令1.6 tail 指令1.7 date 指令1.8 cal 指令1.9 find 指令1.10 grep 指令1.11 zip/unzip 指令1.12 tar 指令1.13 uname –r 指令&#xff1a; 一、指令详细介绍 1.1 cat 指令 语法&#…

每日汇评:黄金有望在复苏之路上重新夺回关键的2025美元关口

周一&#xff0c;金价在本周初延续了其复苏模式&#xff1b; 随着投资者重新评估美联储降息押注&#xff0c;美元跟随美债收益率走软&#xff1b; 黄金买家需要突破21日移动均线2025美元,RSI指数稳定在50以下&#xff1b; 随着买家将上周的复苏模式延续到周一&#xff0c;黄金价…

三防工业平板丨亿道加固平板定制丨三防平板电脑丨提升后勤管理

企业的后勤管理对于运作高效的商业模式至关重要。随着科技的不断发展&#xff0c;加固平板成为提升企业后勤水平的一项关键措施。本文将探讨加固平板在企业后勤管理中的应用和优势&#xff0c;并阐述如何利用这一技术提升企业的运营效率和竞争力。 一、三防加固平板的定义和功能…

云手机受欢迎背后的原因及未来展望

随着办公模式的演变&#xff0c;云手机的热潮迅速兴起。在各种办公领域&#xff0c;云手机正展现出卓越的实际应用效果。近年来&#xff0c;跨境电商行业迎来了蓬勃发展&#xff0c;其与国内电商的差异不仅体现在整体环境上&#xff0c;更在具体的操作层面呈现出独特之处。海外…

python----面向对象

这里写目录标题 面向对象思想类类的定义类名的定义类的构造函数的定义类的属性类的方法定义 继承语法关于构造函数问题 文件操作绝对路径相对路径pycharm获取绝对路径和相对路径文件读写读文件open&#xff08;&#xff09;read&#xff08;&#xff09;readline&#xff08;&a…

Python(九十三)函数的参数总结

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

网站常见的反爬手段及反反爬思路

摘要:介绍常见的反爬手段和反反爬思路&#xff0c;内容详细具体&#xff0c;明晰解释每一步&#xff0c;非常适合小白和初学者学习&#xff01;&#xff01;&#xff01; 目录 一、明确几个概念 二、常见的反爬手段及反反爬思路 1、检测user-agent 2、ip 访问频率的限制 …

Stochastic Depth 原理与代码解析

paper&#xff1a;Deep Networks with Stochastic Depth official implementation&#xff1a;https://github.com/yueatsprograms/Stochastic_Depth third-party implementation&#xff1a;https://github.com/open-mmlab/mmcv/blob/main/mmcv/cnn/bricks/drop.py 存在的问…

【day01】每天三道 java后端面试题:JDK、JRE和JVM | 字节码 | ACID

文章目录 1. JDK, JRE, JVM分别是什么&#xff1f;有什么区别&#xff1f;2. 什么是字节码&#xff1f;采用字节码的最大好处是什么&#xff1f;3. 什么是数据库事务&#xff1f;讲一下事务的ACID特性。 1. JDK, JRE, JVM分别是什么&#xff1f;有什么区别&#xff1f; 答题思路…

深度解析 Transformer 模型:原理、应用与实践指南【收藏版】

深度解析 Transformer 模型&#xff1a;原理、应用与实践指南 1. Transformer 模型的背景与引言2. Transformer 模型的原理解析2.1 自注意力机制&#xff08;Self-Attention&#xff09;自注意力机制原理 2.2 多头注意力机制&#xff08;Multi-Head Attention&#xff09;多头注…

java+vue_springboot企业设备安全信息系统14jbc

企业防爆安全信息系统采用B/S架构&#xff0c;数据库是MySQL。网站的搭建与开发采用了先进的java进行编写&#xff0c;使用了vue框架。该系统从三个对象&#xff1a;由管理员、人员和企业来对系统进行设计构建。主要功能包括&#xff1a;个人信息修改&#xff0c;对人员管理&am…

C++ 浮点数二分 数的三次方根

给定一个浮点数 n &#xff0c;求它的三次方根。 输入格式 共一行&#xff0c;包含一个浮点数 n 。 输出格式 共一行&#xff0c;包含一个浮点数&#xff0c;表示问题的解。 注意&#xff0c;结果保留 6 位小数。 数据范围 −10000≤n≤10000 输入样例&#xff1a; 1000.00…

树与二叉树

树与二叉树 文章目录 树与二叉树一、树的概念及结构1.、树的概念2、树的相关概念1.3 树的表示 二、二叉树1.概念2、特殊的二叉树3、二叉树的性质4、二叉树的存储结构 三、二叉树的顺序结构及实现1、二叉树的顺序结构2、堆的概念及结构3、堆的实现 四、二叉树链式结构的实现1、遍…

python统计分析——一元线性回归分析

参考资料&#xff1a;用python动手学统计学 1、导入库 # 导入库 # 用于数值计算的库 import numpy as np import pandas as pd import scipy as sp from scipy import stats # 用于绘图的库 import matplotlib.pyplot as plt import seaborn as sns sns.set() # 用于估计统计…