C++入门——auto、范围for、nullptr

news2024/12/25 22:08:06

下一篇就要类和对象了,剩了点零碎的知识点就浅浅水一篇把


一.   auto关键字

在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的
是一直没有人去使用它,这是由于变量本身就具备生命周期,使用auto修饰函数实在是多余。

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

简单来说,其实auto声明的变量可以依照初始化的内容来自动识别类型。

int TestAuto()
{
    return 10;
}
int main()
{
    int a = 10;
    auto b = a;
    auto c = 'a';
    auto* e = &a;//等价于auto e=&a;
    auto d = TestAuto();
    return 0;
}

而为了验证这一点,我们可以使用typeid关键字来得到各个变量的类型

int TestAuto()
{
	return 10;
}
int main()
{
	int a = 10;
	auto b = a;
	auto c = 'a';
	auto d = TestAuto();
	auto e = &a;
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
	cout << typeid(e).name() << endl;
	return 0;
}

 注意

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

因此,auto也不能作为函数的参数

2.在上面我们说到,auto声明指针类型时,auto与auto*没有区别,但是,在声明引用类型时,必须使用auto&

	int a = 10;
	auto& b = a;
	cout << typeid(b).name() << endl;

但由于一些不可控的因素(我也不知道为什么),打印类型时依旧时int

但改变b时a也会改变,这也就证实了b是a的别名,这里就不多做讨论了

3.同样,auto也会识别const修饰的类型,也可以使用const修饰auto

	const int a = 10;
	auto b = a;
	const auto c = a;

4.而在同一行定义多个变量时,变量的类型需要一致,这是由于auto只对第一个类型进行推导,用推导出来的类型定义该行所有变量

5.还有一点就是,auto不能直接用来声明数组,这一点当做规定记住即可



二.   范围for

在c语言的学习中,经常需要去遍历数组

int nums[5] = { 1,2,3,4,5 };
for (int i = 0; i < 5; i++)
{
	printf("%d", nums[i]);
}

而在遍历时,往往格式都是固定的,在写循环范围时可能出错

因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范
围内用于迭代的变量,第二部分则表示被迭代的范围。

概念可能看不太懂,我们直接改写一下上面的遍历

	int nums[5] = { 1,2,3,4,5 };
	for(int e:nums)
	{
		cout << e << " ";
	}

大致理解一下,便是将数组的每一个元素依次赋给变量e,并做出相应的操作

而我们也可以使用auto来识别数组的类型,进而增加这段代码的普遍性 

而在进行数组遍历时,有时会对这个数组进行改变,例如我们想让数组的每个元素加一

若我们依旧采用上述方式

	int nums[5] = { 1,2,3,4,5 };
	for(auto e:nums)
	{
		e++;
	}
	for(auto e:nums)
	{
		cout << e << " ";
	}

我们会发现数组没有被改变。

这是因为,这里的e只是数组中每个元素的拷贝,相当于函数中的传值调用,无法做到改变。而在函数传参中,我们可以使用指针或引用,而在这里,由于赋值的是数组中的每个元素,而不是地址,所以不能使用指针,只能使用引用

	int nums[5] = { 1,2,3,4,5 };
	for(auto& e:nums)
	{
		e++;
	}
	for(auto e:nums)
	{
		cout << e << " ";
	}

而在范围for内的数组,我们需要的是整个数组,而若是在函数内范围for使用传参传入的数组,由于会发生退化,数组名传参后会变为指针类型,所以会出现错误



三.   nullptr

在C语言指针的使用中,我们有时会将指针初始化为NULL

int* p=NULL;

在本质上,NULL是一个宏定义

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

在c语言中

#define NULL (void* (0) )

这是没有什么问题的

而在C++中

#define NULL 0

内部是这样的,这也就使得int* p=NULL与int* p=0本质上是一样的

这种用法在大多时候是没有问题的,但有时还是会出现问题

例如以下的函数重载

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

正如我们上面所讲的, 即使第二中传参我们想要传的是指针,但本质上传的还是0,因此会调用第一个函数

为了解决类似的问题,C++11引入了新关键字nullptr,表示指针空值

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

这样便能解决上面的问题 

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

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

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

相关文章

算法及时间、空间复杂度

算法 算法是对问题求解过程的一种描述&#xff0c;是为解决一个或一类问题给出的一个确定的、有限长的操作序列。严格说来&#xff0c;一个算法必须满足以下5个重要特性&#xff1a; &#xff08;1&#xff09;有穷性&#xff1a;对于任意一组合法的输入值&#xff0c;在执行有…

【数据结构与算法——C语言版】5. 排序算法(2)——冒泡排序

前言 上篇文章【数据结构与算法——C语言版】4. 排序算法&#xff08;1&#xff09;——选择排序我们介绍了排序算法中的选择排序&#xff0c;其时间复杂度是O(n2)&#xff0c;本篇文章我们将介绍另一种同样时间复杂度是O(n2)的排序算法——冒牌排序&#xff0c;这两种算法思路…

ChatGPT背后的开源AI框架Ray,现在值10亿美元

Ray 被 OpenAI、亚马逊等科技公司用来开发大模型&#xff0c;是最近异军突起的框架。 最近一段时间&#xff0c;文本生成的人工智能在互联网上掀起了一阵风暴&#xff1a;ChatGPT 因为可以对人们能想到的几乎任何问题提供非常详细、近乎逼真的回答而受到追捧。大模型应用的出现…

Mapper代理开发案例及MyBatis核心

本片文章需要参考我的前一篇文章&#xff1a;MyBatis入门案例引入总结&#xff0c;使用mapper代理开发的好处就是可以解决开发中硬编码的问题和简化后期的SQL执行。使用这种方式可以不用写接口的实现类&#xff0c;免除了复杂的方法&#xff0c;使得代码更加清晰易懂按照以前的…

vue的过渡动画(有vue的动画库和ui库的介绍)

一、概念 Vue 在插入、更新或者移除 DOM 时&#xff0c;提供多种不同方式的应用过渡效果。 二、默认过渡 <template><div><button click"isShow!isShow">显示/隐藏</button><transition appear><h1 v-show"isShow" cl…

过滤器和拦截器的使用及管理

参考&#xff1a;(70条消息) Spring过滤器和拦截器的区别_yjc0403的博客-CSDN博客https://www.cnblogs.com/colin220/p/9606412.htm概述过滤器&#xff1a;是在javaweb中&#xff0c;你传入的request、response提前过滤掉一些信息&#xff0c;或者提前设置一些参数&#xff0c;…

Anaconda安装之后Spyder打不开解决办法--目前有用 jupyter notebook 无法正常运行2023.1.7

纯纯小白&#xff0c;探索一天&#xff0c;终于成功&#xff0c;需要我的经历没有白费&#xff0c;让大家少走弯路。 问题描述 从官网下载Anaconda之后&#xff0c;安装&#xff0c;一切正常。打开Anaconda navigator在弹出窗口选择了更新&#xff08;我怀疑这就根源&#xf…

Js逆向教程24-作用域和自执行函数

作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; Js逆向教程24-作用域和自执行函数 一、变量作用域 1.1局部变量 function jb() {var a"我是局部变量"return a; }1.2全局变…

【Java寒假打卡】Java基础-异常

【Java寒假打卡】Java基础-异常异常概述throws声明异常throw抛出异常try-catch 抛出异常throwable的成员方法异常概述 Exception:称之为异常类&#xff0c;他表示程序本身可以处理的问题 RuntimeException及其子类&#xff1a;运行时异常。&#xff08;空指针异常&#xff0c;…

JUC总结系列篇 (二) : 对线程的理解和使用总结

文章内容&#xff1a; 一.为什么需要多线程 二.线程的创建 三.线程的方法sleep(),run(),wait(),yeid(),join(),interrupt()等方法归纳总结 四.线程的状态及其转换 五.线程的交替执行案例 六.多个线程依次执行案例 七.多线程并发带来的线程安全问题 一.为什么需要多线程&#x…

Linux项目自动化构建工具-make/Makefile

一、前言 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力。一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的规则来指定&#xff0c;哪些文件需要先编译&#xff0c;哪些文件…

前端入门笔记 04 —— Web(html CSS)布局

响应式布局 屏幕尺寸变化&#xff0c;需要响应式网页设计RWD web页面适应不同屏幕宽度因素 液态站点&#xff0c;拉伸充满浏览器窗口 小屏幕挤成一团&#xff0c;大屏幕空白间隙过大固定宽度 像素为单位固定尺寸 小屏幕滚动&#xff0c;大屏幕空白 实现 设置meta标签媒体查…

数据结构入门5-1(数和二叉树)

目录 注 树和二叉树的定义 树的定义 树的基本术语 二叉树的定义 树和二叉树的抽象数据类型定义 二叉树的性质和存储结构 二叉树的性质 二叉树的存储结构 1. 顺序存储结构 2. 链式存储结构 遍历二叉树和线索二叉树 遍历二叉树&#xff08;traversing binary tree&a…

加密与安全

目录 一、编码算法 1.1、ASCII 1.1.1、ASCII简介 1.1.2、ASCII产生原因 1.1.3、表达方式 1.1.4、标准表 1.1.5、大小规则 1.2、Unicode 1.2.1简介 1.2.2编码和实现 1.3、汉字编码 1.3.1、GB2312-80 标准 1.3.2、GBK 编码标准 1.3.3、GB18030编码标准 1.4、URL编…

【Node】中Express框架连接Mysql实现用户注册接口

Node.js中Express框架连接Mysql实现用户注册接口 处理用户注册接口简单分为三步&#xff1a; 1、注册校验 2、完善逻辑 3、拆分模块 拆分模块能够使部分功能能够复用&#xff0c;封装好各个模块使得模块间只能通过有限的接口互相访问&#xff0c;从而降低耦合&#xff0c;拆分模…

LeetCode[1046]最后一块石头的重量

难度&#xff1a;简单 题目&#xff1a; 有一堆石头&#xff0c;每块石头的重量都是正整数。每一回合&#xff0c;从中选出两块最重的 石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结果如下&#xff1a;如果 x …

『年度总结』时光如梭 | 再见 2022 | 你好 2023

⭐创作时间2022年12月31日⭐ ✨结果一直到现在才发&#xff0c;说真的写年度总结还是第一次写比较不熟练&#xff0c;去年有这个活动也有佬叫我参加&#xff0c;不过没参加。今年想着有时间来写下的&#xff0c;结果写到现在才发&#xff0c;这东西说真的挺难写的&#…

机器视觉(九):图像配准

目录&#xff1a; 机器视觉&#xff08;一&#xff09;&#xff1a;概述 机器视觉&#xff08;二&#xff09;&#xff1a;机器视觉硬件技术 机器视觉&#xff08;三&#xff09;&#xff1a;摄像机标定技术 机器视觉&#xff08;四&#xff09;&#xff1a;空域图像增强 …

python简单爬虫

爬虫真是一件有意思的事儿啊&#xff0c;之前写过爬虫&#xff0c;用的是urllib2、BeautifulSoup实现简单爬虫&#xff0c;scrapy也有实现过。最近想更好的学习爬虫&#xff0c;那么就尽可能的做记录吧。这篇博客就我今天的一个学习过程写写吧。 一 正则表达式 正则表达式是一…

格式化电脑重装系统怎么操作

​电脑一但中毒的电脑必须重装系统&#xff0c;而且需要格式化后重装系统&#xff0c;才能将病毒铲除&#xff0c;那么如何将电脑格式化后重装系统呢&#xff1f;能够实现电脑格式化重装系统的方法是U盘重装和光盘重装&#xff0c;由于部分电脑没有光驱&#xff0c;建议用U盘&a…