目录
<一>auto的简介
在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的 是一直没有人去使用它,大家可思考下为什么? C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一 个新的类型指示符来指示编译器,auto声明的变必须由编译器在编译时期推导而得。自动推导类型。
using namespace std;
#include<iostream>
int TestAuto()
{
return 10;
}
int main()
{
int a = 10;
auto b = a;
auto c = 'a';
auto d = TestAuto();
//typeid()是一个获取表达式信息的函数,是一个类对象,name是类对象的成员函数。
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << typeid(d).name() << endl;
//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
return 0;
}
运行结果
注意:使用auto定义变量时必须对其进行初始化
<二>使用明细
1, auto与指针和引用结合起来使用
在声明指针类型的时候,auto和auto* 没有任何区别,但是声明引用的时候必须加&
2.在同一行定义多个变量
当在同一行定义多个变量的时候这些必须是相同类型的,因为编译器实际上只是对第一个类型进行推导,然后利用推导出来的类型定义其他变量
<三>不能用auto推导的场景
1.auto不能作为函数的参数
2,auto不能直接用来定义数组。
3. 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法
4. auto在实际中最常见的优势用法就是跟后面会讲到的C++11提供的新式for循环,还有 lambda表达式等进行配合使用。
<四>范围for循环
对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因 此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:
第一部分是范 围内用于迭代的变量,
第二部分则表示被迭代的范围。
int main()
{
int array[10] = { 1,2,3,4,5,6,7,8,9,0 };
for (int e : array)//可以使用int 接收
{
cout << e << " ";
}
for (auto e : array)//使用auto的意思是可以适配更多的类型(自动适配类型)
{
cout << e <<" ";
}
printf("\n");
for (auto& e : array)//这里用引用来接收可以修改它
{
e *= 2;
}
printf("\n");
for (auto e : array)
{
cout << e << " ";
}
//和普通循环一样可以用continue break 来结束循环
return 0;
}
<五>范围for循环的使用条件
1. for循环迭代的范围必须是确定的
对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供 begin和end的方法,begin和end就是for循环迭代的范围。 注意:以下代码就有问题,因为for的范围不确定
void main()
{
int array[10] = { 1,2,3,4,5,6,7,8,9,0 };
int* a = array;
for (int e : a) //错误 此基于范围的“for”语句需要适合的 "begin" 函数,但未找到。
{
cout << e << " ";
}
}
void test(int arr[])
{
for (auto a : arr)//这里的指针类型不是数组
{
cout << a << endl;
}
}
<六>c++的空指针
C语言的NULL实际上是一个宏变量,在<stddef.h>中可以看到,
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何 种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:
void fun(int)
{
cout << "fun(int)" << endl;
}
void fun(int*)
{
cout << "fun(int*)" << endl;
}
int main()
{
fun(0);
fun(NULL);//这里本意调用第二个函数,实际却是第一个函数。
fun((int*)NULL);
fun(nullptr);
return 0;
}
结果为:
在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器 默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。
注意
- nullptr使用的时候不需要包含头文件,c++11将他作为关键字的形式给出,NULL使用的时候一般要包含头文件,因为他是定义在<stddef.h>头文件中的一个宏。
- 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
- 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。