目录
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++引入了一种更为简单的方式:
意思就是,auto关键字能够自动推导变量的类型。当然你是用 auto 时,编译器无法推出变量的类型就会报错的啦!
int main()
{
auto a = 10; //正确的写法
auto e; //错误的写法
}
2. auto的使用
int main()
{
auto e;
}
上面提到 这种写法是不正确的,原因是什么呢?来看看标准化的解释:
2.1 auto与指针和引用结合起来使用
int main()
{
auto a = 10;
auto pa1 =
auto* pa2 =
auto 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来自动推导得到的变量类型。
你如果要改变原数组的值,你可以使用引用哦!像下面这样:
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循环的底层是使用迭代器来完成遍历的操作的。至于迭代器是个啥,后面会讲到!!!