auto用来干啥
在C语言中,auto是用来修饰局部变量的,意味着该变量在该代码块内要有效,出代码块自动销毁
但是在C++中,有了新的用法:自动推导变量类型
int a = 10;
auto b = a; //自动推导b的类型为a的类型(整形)
auto c = 'c';//自动推导c的类型为字符型
auto sum = Add(a,b);//自动推导sum的类型为函数的返回值类型
/* 分别打印变量类型的名字 --- typeid()*/
cout<<typeid(b).name<<endl;
cout<<typeid(c).name<<endl;
cout<<typeid(sum).name<<endl;
当然auto的使用场景不限于此
auto的使用场景
基于范围的for循环
通常在写for循环的时候,需要我们自己标注好循环的范围
但是有时会犯错误,C++因此引入了范围for循环
for循环后的括号由冒号:
分为两部分:第一部分是范围内用于迭代的变量, 第二部分则表示被迭代的范围.
int arr[]={1,2,3,,4,5,6,7,8};
for(auto e : arr)
{
cout<<e<<" ";
}
//自动依次取 arr的元素赋值给e
这样,不管数组元素的类型是什么,都会自动打印每一个元素
注意:范围for循环什么时候不能用
for循环的迭代返回必须是确定的,对于数组而言,就是第一个元素到最后一个元素
比如:
void test(int arr[])
{
for(int e:arr)
{
cout<<e<<" ";
}
}
// 数组形参其实就是首元素地址,而非整个数组
// 所以此时迭代找不到范围,出错!
自动推导变量类型
如果变量的类型特别长,那么写起来就很麻烦
这时候就体现出来auto的价值了
举个例子:
std::map<std::string,std::string>::iterator it = dict.begin()
就可以替换成:auto it = dict.begin()
auto的使用细节
- auto与指针和引用结合起来使用
auto与指针:auto
与auto*
一样
auto与引用:auto&
int x = 10;
auto a = &x;//自动推导a是int*
auto* b = &a;//auto* 表明b是一个指针,这时候右边必须传指针
auto& c = x;// 表明c是一个引用(别名),自动推导c的类型为int
这样就可以利用范围for来修改数组元素了
//利用引用,e就是每一次该元素的别名,利用别名进行修改元素
for(auto& e : arr)
{
e++;//每个元素++
}
*********************************************
//利用指针可以吗?--不可以!
for(auto* e:arr)
{
*e?
}
/* 注意:范围for是不可以用指针的
因为范围for是把数组的每一个元素传递
只能用传值接受和传引用接收,指针不识别*/
- 在同一行定义多个变量
最好不用auto一行定义多个,如果多个变量的类型存在不同,是无法识别的!
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对 第一个类型进行推导,然后用推导出来的类型定义其他变量
auto a = 10, b = 30; // 这样可以识别
auto c = 10, d = 30.0;// 一个是int,一个是double。无法识别
注意
使用auto定义变量时必须对其进行初始化,因为在编译阶段,编译器就会根据后面初始化给的值来推导出auto的类型。并在编译期间就会把auto替换为变量的实际类型
auto不能使用的场景
- auto不能作为函数参数
//此时代码编译会出错,auto不能作为形参类型
//因为编译器无法推导出形参的实际类型
void test(auto a)
{
/***/
}
准确点来说,函数调用需要开辟栈帧。而编译器给函数开辟栈帧之前就已经根据形参、函数体里的开辟的空间的大小算好要开辟的栈帧大小了。而auto的形参对于编译器来说,不知道要开辟多大的空间。所以会报错
- auto不用来声明数组
void test()
{
int a[]={1,2,3};
auto b[]={4,5,6};
//编译器无法自动推导数组的类型
}
标签:变量,推导,int,auto,C++,关键字,编译器,类型
From: https://www.cnblogs.com/iiianKor/p/17982025