往期文章: C++学习笔记
文章目录
前言
auto关键字像是一根铁吸管,一口气扎入命名空间取出我们要的变量名。auto关键字的存在意义是:解决了C++由于新增的命名空间后出现的新问题冗长的变量类型名字。因为C++有了命名空间后当我们使用某个命名空间内部的变量时我们要像剥洋葱一样把这个变量所属的所有命名空间一层层按顺序全写出来才能使用它,这个过程过于痛苦,所以有了auto关键字帮助我们一次性把类型名表示出来。
auto关键字可以自动推理出它所属变量的类型,它可以根据代码的前后文推理出它所属的变量是什么类型,并自己代替冗长的命名空间。不过要注意,auto只是一根铁吸管,它的功能并不多,接下来会在auto的特性里面阐述它的功能限制。
一、auto的出现与功能变化
在早期C/C++中auto的含义是:使用auto修饰的变量是具有自动存储器的局部变量。(使用场景不多)
随着程序越来越复杂,程序中遇到的类型名也逐渐冗杂,主要体现在在:
- 类型难以拼写;
- 类型名意义不明容易导致报错
因此,在C++11的更新中,auto失去存储能力,作为类型指示符指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
PS:使用auto定义变量时必须对其初始化,给予它一种类型,编译器会自动推测auto的类型。auto并不是声明了变量的类型,auto只是占用了类型声明的位置,编译器在编译过程中会把auto换成它被给予的类型。
二、auto的使用
1.auto与指针结合使用
auto声明使用指针类型时,auto可通过变量名自动识别指针的类型,不需要加*来提示编译器;
2.auto与引用结合使用
auto声明使用引用类型时必须加 &,来提醒编译器引用类型。(即auto作引用类型时也要加&)
3.auto类型指示举例
不论是整型,浮点型、地址、字符型或别名,auto都可以完美地识别任何类型的变量。甚至它们自己当别名都可以。
#include<iostream>
using namespace std;
int main()
{
//整形
int x = 10;
int& y = x;
auto mao1 = x; //整型
cout << typeid(mao1).name() << endl;
auto& mao2 = x; //auto作为整型的别名
cout << typeid(mao2).name() << endl;
auto mao3 = &x; //整型地址
cout << typeid(mao3).name() << endl;
auto mao4 = y; //整型的别名
cout << typeid(mao4).name() << endl;
cout << endl;
//字符型
char m = 'a';
const char* n = "abc";
auto mao5 = m; //字符型
cout << typeid(mao5).name() << endl;
auto mao6 = n; //字符地址
cout << typeid(mao6).name() << endl;
cout << endl;
//数组
int arr[] = { 0 };
int* p = arr;
auto mao7 = p; //数组地址
cout << typeid(mao7).name() << endl;
cout << endl;
//浮点型
float aa = 1.1;
auto mao8 = aa;
cout << typeid(mao8).name() << endl;
double bb = 2.2;
auto mao9 = bb;
cout << typeid(mao9).name() << endl;
return 0;
}
三、auto的特性
- 不要给予auto多个变量
当在auto的同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量; - auto不能作为函数参数,因为编译器不能对auto类型变量的实际类型进行推导;
- auto不能直接用来声明数组 ;
- 为了不与C语言的auto功能冲突,C++11只允许auto作为类型指示符的用法。
- auto的存在使得新式for循环被发明,还有lambda表达式等进行配合使用。
四、基于范围的for循环
在C++11中新式的范围for已经超越了老式的for循环。对于一个有范围的集合而言,说明循环的范围是多余的,因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示迭代范围。
代码案例如下:
#include<iostream>
using namespace std;
int main()
{
int array[] = { 1, 2, 3, 4, 5 };
for (auto& e : array)
e *= 2;
for (auto e : array)
cout << e << " ";
return 0;
}
PS.与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。
五、指针空值nullptr(C++11)
在C++里指针空值指定使用一个新的关键字nullptr实现,在良好的编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化:
int* p1 = nullptr;
int* p2 = 0;
六、查询变量类型的函数——typeid(变量名).name()
#include<iostream>
using namespace std;
int main()
{
int a = 1;
auto b = a;
cout << typeid(b).name() << endl;
return 0;
}