C语言中提供了存储说明符auto,register,extern,static说明的四种存储类别。四种存储类别说明符有两种存储期:自动存储期和静态存储期。其中auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块是被建立,它在该程序块活动时存在,退出该程序块时撤销。
在函数内部定义的变量成为局部变量。在某些C语言教材中,局部变量称为自动变量,这就与使用可选关键字a u t o定义局部变量这一作法保持一致。在C语言中使用auto关键字声明一个变量为自动变量,是C语言中应用最广泛(隐含使用)的一种类型,在函数内定义变量时,如果没有被声明为其他类型的变量都是自动变量,也就是说,省去类型说明符auto的都是自动变量。这里的其他类型指的是变量的存储类型即:静态类型变量(static )、寄存器类型变量(register)和外部类型变量(extern)。例:
void Test() {
auto int x = 10; //定义自动变量x,auto可以省略
int y; //y和z都为自动变量,如果省略了auto 关键字则隐含表示为auto类型
}
在C语言中使用auto定义的变量可以不予初始化,但在C++中必须初始化。自动变量,在函数调用时分配存储空间,当完成调用时释放存储空间。当然也存在下面这种形式:
auto val; //当省略数据类型,只使用auto修饰变量,在C语言中默认变量为int型
在C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指
示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
int TestAuto()
{
return 10;
}
int main()
{
int a = 10; // a为 int类型
auto b = a; // b由a推理得到 int类型
auto c = 'a'; // c为 char类型
auto f = "abcd"; // f为 常量字符串指针类型
auto d = TestAuto();
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << typeid(f).name() << endl;
cout << typeid(d).name() << endl;
system("pause");
// auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
return 0;
}
1)auto f = "abcd"; 在此, f为 常量字符串指针类型,为char * const 类型在此表示所指向的地址不能改变。若为const char * 表示所指向内容不能变。
2)auto e; 无法通过编译,未进行初始化其不代表实际类型,无法进行类型推导。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
int main() {
int x = 10;
auto a = &x;
auto* b = &x;
auto& c = x;
cout << typeid(a).name() << endl; // int *
cout << typeid(b).name() << endl; // int *
cout << typeid(c).name() << endl; // 引用无法显式显示出来,其为a的别名,相当于typeid(a)
*a = 20;
*b = 30;
c = 40;
system("pause");
return 0;
}
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
void TestAuto()
{
auto a = 1, b = 2;
auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a) // 没有初始化表达式,参数不能为auto类型,即便auto a = 5;也不可以
{}
void TestAuto()
{
int a[] = {1,2,3};
auto b[] = {4,5,6};
}
1. 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法
2. auto在实际中最常见的优势用法就是跟以后会讲到的C++11提供的新式for循环,还有lambda表达式等进行配合使用。
3. auto不能定义类的非静态成员变量(待补充))
4. 实例化模板时不能使用auto作为模板参数(待补充)