C++ auto类型总结
一. 用途
auto是c++程序设计语言的关键字。用于两种情况
- 声明变量时根据初始化表达式自动推断该变量的类型
- 声明函数时函数返回值的占位符
二. 用法
auto可以在声明变量时自动推断被声明变量的类型,如:
auto f = 3.14; //double
auto s("hello"); //const char* 这里并不是string类型
auto z = new auto(9); //int *
auto x1 = 5, x2 = 3.4, x3 = 'c'; //错误,因为必须要声明为同一类型
但是,这么简单的变量声明类型,不建议用auto关键字,而是应更清晰地直接写出其类型。
auto关键字更适用于类型冗长复杂、变量使用范围专一时,使程序更清晰易读。如:
(可以避免太长的类型声明)
std::vector<int> vect;
for(auto it = vect.begin(); it != vect.end(); ++it){
std::cin >> *it
//it的类型是std::vector<int>::iterator 此处可以避免太长的类型声明
}
三. 优势
(1)拥有初始化表达式的复杂类型变量声明时简化代码。
比如:
#include <cstring>
#include <cstdlib>
#include <vector>
void loopover(std::vector<std::string>&vs)
{
std::vector<std::string>::iterator i = vs.begin();
for(;i<vs.end();i++){
}
}
变为:
#include <cstring>
#include <cstdlib>
#include <vector>
void loopover(std::vector<std::string>&vs)
{
for(auto i=vs.begin();;i<vs.end();i++){
}
}
使用std::vectorstd::string::iterator来定义i是C++常用的良好的习惯,但是这样长的声明带来了代码可读性的困难,因此引入auto,使代码可读性增加。并且使用STL将会变得更加容易
(2)可以避免类型声明时的麻烦而且避免类型声明时的错误。
但是auto不能解决所有的精度问题。比如:
#include <iostream>
using namespace std;
int main()
{
unsigned int a=4294967295;//最大的unsigned int值
unsigned int b=1;
auto c=a+b;
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
cout<<"c="<<c<<endl; // c = 0
}
上面代码中,程序员希望通过声明变量c为auto就能解决a+b溢出的问题。而实际上由于a+b返回的依然是unsigned int的值,姑且c的类型依然被推导为unsigned int,auto并不能帮上忙。这个跟动态类型语言中数据hi自动进行拓展的特性还是不一样的。
四. 需要注意的地方
(1)可以用valatile,pointer(*),reference(&),rvalue reference(&&) 来修饰auto
auto k = 5;
auto* pK = new auto(k); // 一维数组
auto** ppK = new auto(&k); // 二维数组
const auto n = 6; // 说明 n 是常量
(2)用auto声明的变量必须初始化
(3)auto不能与其他类型组合连用
auto int p; //这是auto旧版本的写法,现在不允许这样写了
(4)函数和模板参数不能被声明为auto
(5)定义在堆上的变量,使用了auto的表达式必须被初始化(c中内存的堆区是用来 存放new或者malloc出来的对象)
C语言在内存中一共分为如下几个区域,分别是:
1. 内存栈区: 存放局部变量名;
2. 内存堆区: 存放new或者malloc出来的对象;
3. 常数区: 存放局部变量或者全局变量的值;
4. 静态区: 用于存放全局变量或者静态变量;
5. 代码区:二进制代码。
int* p = new auto(0); //fine
int* pp = new auto(); // should be initialized
auto x = new auto(); // Hmmm ... no intializer
auto* y = new auto(9); // Fine. Here y is a int*
auto z = new auto(9); //Fine. Here z is a int* (It is not just an int)
(6)以为auto是一个占位符,并不是一个他自己的类型,因此不能用于类型转换或其他一些操作,如sizeof和typeid
auto* x = new auto(3.3);
auto y = (int)*x;
x++;
*x=4;
x--;
cout<<sizeof(y)<<" "<<y<<endl; //sizeof(y)=4 y=3 因为y是int类型,占四个字节
auto p=2.3;
cout<<sizeof(p)<<endl; //sizeof(p)=8 因为p是double类型,占八个字节
int w = 3;
int e = (auto)w; // 这里会报错,因为auto是一个占位符,并不是一个类型,因此并不能类型转换
(7)定义在一个auto序列的变量必须始终推导成同一类型
auto x1 = 5, x2 = 5.0, x3='r'; //错误,必须是初始化为同一类型
(8)auto不能自动推导成CV-qualifiers (constant & volatile qualifiers)(CV限定符)
1.CV限定符,可出现于任何类型说明符(包括声明文法的 声明说明符序列)中,以指定被声明对象或被命名类型的常量性(constness)或易变性(volatility)。
2.有两种,一种是const,表示常量。另一种是volatile,表示变量。
(9)auto会退化成指向数组的指针,除非被声明为引用
原文链接:C++ auto类型用法总结