auto简介
在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量。
C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
int Add(int left, int right)
{
return left + right;
}
int main()
{
int a = 10;
auto b = a;
auto c = 'c';
auto d = 12.34;
auto r = Add(10, 20);
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << typeid(d).name() << endl;
cout << typeid(r).name() << endl:
return 0;
}
auto的使用细则
1. auto与指针和引用结合起来使用:
用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
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;
return 0;
}
2. 在同一行定义多个变量
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
void TestAuto()
{
auto a = 1, b = 2;
auto c = 3, d = 4.0;
}
3. auto不能推导的场景
① auto不能作为函数的参数
② auto不能直接用来声明数组:因为但凡定义一个数组你需要提前声明数组里边的元素类型,然后才给这个数组开辟出对应类型的空间,如果一开始就用AUTO那么程序是无法为数组申请出空间的。
4. auto最常用的地方:
①auto实际上是很占资源的,因为每次使用编译器都会用它去推导出对应类型,所以一般情况下还是老老实实手敲。当有的类型过于冗长,我们可以用AUTO来使代码变得轻巧:
#include <map>
#include <string>
int main()
{
std::map<std::string, std::string> m{ { "apple", "苹果" }, {"orange","橙子"} };
std::map<std::string, std::string>::iterator it1 = m.begin();
auto it2 = m.begin();
return 0;
}
②AUTO占位符还可以用于遍历一个数组,前提是这个数组的范围已经被确定,也就是说这个数组提前已经被定义出来了,我们在定义数组的时候,编译器已经提前知道了数组的大小,这些信息已经被储存在了编译器中,如果我们还用以前的方法循环遍历,还得多算一遍数组的大小,语法:
int main(){
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto e : arr){
cout << e << endl;
}
return 0;
}
解释for(auto e:arr):定义一个变量e,它的类型为数组arr中所储存的数据类型为int,arr是数组首元素的地址,也是这块有范围的空间的首地址,其次我们还可以定义一个引用类型的变量:for(auto &e:arr),这样的话我们就相当于可以通过修改e的值来直接修改数组里边的内容。
遍历二维数组
思考一下如果arr是一个二维数组呢,他会输出什么?
int main(){
int arr[][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (auto e : arr){
cout << e << endl;
}
return 0;
}
毫无疑问,在这时auto的类型还是数组的元素类型,此时数组的类型是一个一维数组,该一维数组中有四个int类型的元素。我们又知道,对于一个一维数组,数组名就相当于数组的首地址,所以他肯定会输出三个地址