【C++】auto 范围for nullptr

news2024/11/17 20:29:44

目录

一,auto

1,类型别名思考

2,auto 简介

3,auto 的使用细则

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

2,同一行定义多个变量

3,auto 不能推导的场景

二,基于范围的for循环

1,范围 for 的语法

2,范围 for 的使用条件

三,指针空值 nullptr


一,auto

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::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 声明的变量必须由编译器在编译时期推导而得。

来看一段代码;

#include<iostream>
using namespace std;
int TestAuto()
{
	return 10;
}
int main()
{
	int a = 10;
	auto b = a;
	auto c = 'a';
	auto d = TestAuto();
	cout << typeid(b).name << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
	//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
	return 0;
}

auto 会自动匹配相对应的类型;

注意:

使用 auto 定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导 auto 的实际类型。

因此 auto 并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编 译期会将 auto替换为变量实际的类型。

3,auto 的使用细则

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

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

继续先看一段代码;

#include<iostream>
using namespace std;
int main()
{
	int x = 10;
	auto a = &x;
	auto* b = &x;
	auto& c = x;
	cout << typeid(a).name() << endl;
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	*a = 20;
	*b = 30;
	c = 40;
	cout << x << endl;
	return 0;
}

可以看到 auto 完全没有问题;

2,同一行定义多个变量

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

看代码:

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

使用 auto 时,同一行定义多个变量时,这些变量必须是相同的类型;

3,auto 不能推导的场景

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

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

auto 不能作为参数类型;

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

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

auto 声明不了数组;

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

auto 在实际中最常见的优势用法就是跟以后会讲到的 C++11 提供的新式 for 循环,还有 lambda 表达式等进行配合使用

二,基于范围的for循环

1,范围 for 的语法

在 C 语言中如果要遍历一个数组,可以按照以下方式进行:

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 << " ";
}

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

2,范围 for 的使用条件

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

对于数组而言,就是数组中第一个元素和最后一个元素的范围;

对于类而言,应该提供 begin 和 end 的方法,begin 和 end 就是 for 循环迭代的范围。

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

void TestFor(int array[])
{
    for(auto& e : array)
        cout<< e <<endl;
}

这是为什么呢?因为此时的 array 是指针,是地址,并不是代表数组,没有边界感,所有会报错;

三,指针空值 nullptr

在良好的 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。

所以引进了nullptr 就代表 ( void* ) 0 代表真正意义上的空;

注意:

1,在使用 nullptr 表示指针空值时,不需要包含头文件,因为 nullptr 是C++11作为新关键字引入的

2,在 C++11 中,sizeof ( nullptr ) 与 sizeof ( ( void* ) 0 ) 所占的字节数相同。

3,为了提高代码的健壮性,在后续表示指针空值时建议最好使用 null

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

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

相关文章

音频信号的频谱分析实例

在前面的文章 信号频谱分析与功率谱密度 中&#xff0c;我们初步探讨了信号频谱分析的概念&#xff0c;并介绍了其数学工具。本篇文章将结合实例&#xff0c;进一步探讨频谱分析在音频信号处理中的应用。 音频信号的频谱分析是一种将时域中的音频信号转换为频域表示的过程&…

华为云CodeArts IDE for Java安装使用教程

本篇内容主要介绍使用华为云CodeArts IDE for Java创建工程、代码补全、运行调试代码、Build构建和测试相关的主要功能。 一、下载安装华为云CodeArts IDE for Java 华为云CodeArts IDE for Java安装要求 至少需要 2 GB RAM &#xff0c;但是推荐8 GB RAM; 至少需要 2.5 GB 硬…

C# Onnx Yolov8 Detect 指纹检测

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace Onnx…

钢水包升降翻转液压系统比例阀放大器

钢水包升降翻转液压系统是一种用于控制钢水包升降和翻转的液压系统。该系统主要由液压泵、液压缸、控制阀和一些辅助元件组成。 钢水包升降翻转液压系统的液压泵将油从油箱中抽出&#xff0c;将油压力提高到一定值&#xff0c;然后通过控制阀将油分配到液压缸中。液压缸内的活…

https证书

SSL证书的作用是确保通过网站传输的数据在客户端和服务器之间是安全、私密的。 它通过建立安全的通信通道来防止数据泄露、中间人攻击以及篡改等安全威胁&#xff0c;提供了身份认证和数据加密的功能。 这样可以确保用户在网站上提交的敏感信息&#xff0c;如个人数据、公司信…

linux常见命令-时间日期类、搜索查找类、压缩和解压类

一、时间日期类 1.date 指令-显示当前日期 基本语法 1) date (功能描述:显示当前时间) 2) date %Y (功能描述:显示当前年份) 3) date %m (功能描述:显示当前月份) 4) date %d (功能描述:显示当前是哪一天) 5) date "%Y-%m-%d %H:%M:%S" (功能描述:显示年月…

0基础学习VR全景平台篇第111篇:全景图拼接和编辑 - PTGui Pro教程

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 前情回顾&#xff1a;上节&#xff0c;我们将源图像导入了PTGui&#xff0c;也设置好了各项参数。 下面我们就开始拼接全景图&#xff0c;并且在编辑器里进行一系列检查错位和设…

Android 如何在Service中使用ViewModel

需求&#xff1a;最近有反馈说&#xff0c;需要在service中使用网络请求&#xff0c;而我网络请求就是封装的ViewModel。然后我就发现&#xff0c;原来service不支持&#xff0c;懵了呀&#xff01;哈哈 还是去看看ViewModel的源码了解下吧。下面有几个介绍的。就不多做赘述了。…

uni-app开发

uni-app 官方手册&#xff1a;uni-app官网 一&#xff1a;tarBar&#xff1a;一级导航栏&#xff0c;即 tab 切换时显示对应页。 在pages.json文件里写入如下代码&#xff1a; 此效果&#xff1a;

ROS学习9:ROS进阶

【Autolabor初级教程】ROS机器人入门 1. action 通信 背景 机器人导航到某个目标点,此过程需要一个节点 A 发布目标信息&#xff0c;然后一个节点 B 接收到请求并控制移动&#xff0c;最终响应目标达成状态信息。乍一看好像是服务通信实现&#xff0c;因为需要 A 发送目标&…

【vSphere 8 自签名证书】企业 CA 签名证书替换 vSphere Machine SSL 证书Ⅲ—— 颁发自签名证书

目录 博文摘要5. 使用 Microsoft 证书颁发机构颁发自签名 SSL 证书5.1 登录MADCS5.2 申请证书5.3 选择证书类型5.4 提交CR5.5 下载 Base 64 编码的证书5.6 导出 CA 证书&#xff08;1&#xff09;打开 cachain.p7b&#xff08;2&#xff09;进入证书导出导向&#xff08;3&…

Mysql高级——锁(2)

4. 锁的内存结构 InnoDB 存储引擎中的锁结构如下&#xff1a; 锁所在的事务信息&#xff1a; 不论是表锁还是行锁&#xff0c;都是在事务执行过程中生成的&#xff0c;哪个事务生成了这个锁结构&#xff0c;这里就记录这个事务的信息。 此锁所在的事务信息在内存结构中只是一…

让世界更精彩,拓世科技新品亮相世界舞台!虚实融合 智兴百业,2023世界VR产业大会正式开幕!

在这个科技重塑未来的时代&#xff0c;每一分、每一秒&#xff0c;科学技术都在飞速发展&#xff0c;成为我们都在经历的现实。世界VR产业大会&#xff0c;让我们再次目睹了科技带来的奇迹。VR、5G、人工智能、元宇宙等新技术&#xff0c;作为社会进步的引擎&#xff0c;正塑造…

Python程序龟速过载怎么办,asyncio并发教程来解决

前言 许多应用程序&#xff0c;尤其在当今的Web应用程序领域&#xff0c;严重依赖I/O操作。这些类型的操作包括从Internet下载网页的内容、通过网络与一组微服务进行通信&#xff0c;或者针对MySQL或Postgres等数据库同时运行多个查询。Web请求或与微服务的通信可能需要数百毫…

【数据结构】——二叉树的基础知识

数概念及结构 数的分类 二叉树、多叉树 数的概念 树是一种非线性的数据结构&#xff0c;它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做树的原因是它看起来像一颗倒挂的树&#xff0c;也就是说它是跟朝上&#xff0c;而叶朝下的。 有一个特殊的节点&…

小红书达人怎么对接,博主沟通流程汇总!

想要在小红书平台进行宣推&#xff0c;就离不开博主的帮助。一般来说&#xff0c;与小红书博主沟通&#xff0c;分为意向沟通、下单沟通、内容沟通和数据沟通方面。今天为大家分享下小红书达人怎么对接&#xff0c;博主沟通流程汇总&#xff01; 一、意向沟通 意向沟通是小红书…

MyBatis中怎样查看执行的sql语句日志?

MyBatis中怎样查看执行的sql语句日志&#xff1f; 在mybatis中我们执行sql语句是通过动态代理接口执行的&#xff0c;我们并不能看到内部的sql的执行情况&#xff0c;所以你执行完一个接口之后&#xff0c;你也不知道sql到底有没有执行&#xff1f;以及sql执行的对不对&#x…

【试题016】逗号表达式例题

1.题目&#xff1a;设int a,b;,则表达式(b2,a5,b,ab)的值是 &#xff1f; 2.代码分析&#xff1a; #include <stdio.h> int main() {//设int a,b;,则表达式(b2,a5,b,ab)的值是 ()int a, b;printf("%d\n", (b 2, a 5, b, a b));//分析&#xff1a;逗号表达…

基于Java+Springboot+Vue前后端分离的商品进销存管管理系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 当今社会&#xff0c;…