· CSDN的uu们,大家好。这里是C++入门的第七讲。
· 座右铭:前路坎坷,披荆斩棘,扶摇直上。
· 博客主页: @姬如祎
· 收录专栏:C++专题
目录
1. 知识引入
2. auto的使用
2.1 auto与指针和引用结合起来使用
2.2 在同一行定义多个变量
2.3 auto不能推导的场景
2.3.1 auto不能作为函数的参数
2.3.2 auto不能直接用来声明数组
3. auto与范围for的结合
1. 知识引入
曾记否,我们在用C语言实现基础的数据结构时,会用到结构体来作为链表的一个节点,像这样:
struct ListNode
{
struct ListNode* next;
int val;
};
int main()
{
struct ListNode node;
}
我们在使用这个节点的时候,前面的变量类型就要写这么多,是不是很烦,很不舒服。当然你也可能会觉得这还好啊,不久两个单词嘛。但是在C++的后续学习过程中你可能会遇到这样的变量类型:
#include<map>
#include<string>
int main()
{
std::map<std::string, std::string>::iterator a;
}
这样看下来是不是觉得写变量的类型还是真的有些麻烦。不过聪明的UU可能想到可以用 typedef 给变量区别名来达到简化的效果,非常棒!但是呢,C++引入了一种更为简单的方式:
C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
意思就是,auto关键字能够自动推导变量的类型。当然你是用 auto 时,编译器无法推出变量的类型就会报错的啦!
int main()
{
auto a = 10; //正确的写法
auto e; //错误的写法
}
2. auto的使用
int main()
{
auto e;
}
上面提到 这种写法是不正确的,原因是什么呢?来看看标准化的解释:
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
2.1 auto与指针和引用结合起来使用
用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须
加&。
int main()
{
auto a = 10;
auto pa1 = &a;
auto* pa2 = &a;
auto& ra = a; //声明引用必须加&
cout << typeid(a).name() << endl;
cout << typeid(pa1).name() << endl;
cout << typeid(pa2).name() << endl;
cout << typeid(ra).name() << endl;
}
为什么声明引用必须加上&呢?原因很简单,拿上面的例子来说,不加&,只是声明了一个 int 类型的变量,然后赋值为 a 的值。另外我们可以使用 typeid(变量).name() 来查看变量的类型。
2.2 在同一行定义多个变量
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译
器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
2.3 auto不能推导的场景
2.3.1 auto不能作为函数的参数
void Func1(auto b) //错误的写法
{
}
void Func2(auto a = 10) //错误的写法
{
}
代码会编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导。缺省的参数也不行哦!
2.3.2 auto不能直接用来声明数组
auto a[4] = { 1,2,3,4 }; //错误的写法
3. auto与范围for的结合
在C++98中我们要遍历数组,会写出这样的代码:
int main()
{
int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
cout << a[i] << " ";
}
但是这种鞋码对于一个本身就有范围的集合来说,我们还去自己写代码来指定他的范围就显得有些多余了!甚至可能哈辉犯错误!因此C++11中引入了基于范围的for循环。for循环后的括号由冒号(:)分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。
int main()
{
int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
cout << a[i] << " ";
for (auto i : a)
cout << i << " ";
for (int i : a)
cout << i << " ";
}
上面的三种写法都是等效的,可以使用auto来自动推导得到的变量类型。
注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。
你如果要改变原数组的值,你可以使用引用哦!像下面这样:
int main()
{
int a[10] = { 0,1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
a[i] += 1;
for (auto& i : a)
i += 1;
for (int& i : a)
i += 1;
}
范围for循环的底层是使用迭代器来完成遍历的操作的。至于迭代器是个啥,后面会讲到!!!