[C++系列] 7. C++auto关键字(C++11)

1. C语言中的auto

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型

2. C++中的auto

在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;
}

[C++系列] 7. C++auto关键字(C++11)_第1张图片

注意:

1)auto f = "abcd";   在此, f为 常量字符串指针类型,为char * const 类型在此表示所指向的地址不能改变。若为const char * 表示所指向内容不能变。

2)auto e; 无法通过编译未进行初始化其不代表实际类型,无法进行类型推导。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。

3. auto使用细则

3.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;  // 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;
}

3.2 在同一行定义多个变量

当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

void TestAuto()
{
    auto a = 1, b = 2; 
    auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}

4. auto不能推导的场景

4.1 auto不能作为函数参数

// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)   // 没有初始化表达式,参数不能为auto类型,即便auto a = 5;也不可以
{}

4.2 auto不能直接用来声明数组

void TestAuto()
{
    int a[] = {1,2,3};
    auto b[] = {4,5,6};
}

4.3 auto几点注意

1. 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法
2. auto在实际中最常见的优势用法就是跟以后会讲到的C++11提供的新式for循环,还有lambda表达式等进行配合使用。
3. auto不能定义类的非静态成员变量(待补充))
4. 实例化模板时不能使用auto作为模板参数(待补充)

你可能感兴趣的:([C++系列],C++,知识点总结)