- 1.auto
- 1.auto的作用
- 2.auto的使用细节
- 3.auto的实用场景
- 2.nullptr
1.C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得
什么意思呢?看代码
#includeusing namespace std; int TestAuto() { return 10; } int main() { int a = 10; auto b = a; auto c = TestAuto(); cout << typeid(a).name() << endl; cout << typeid(b).name() << endl; cout << typeid(c).name() << endl; return 0; }
typeid可以看到变量的类型
运行结果
我们来改了代码再运行一下
可以看到auto的作用就是推导函数的类型
但是使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
2.auto的使用细节1.auto可以和指针和引用一起使用
代码
#includeusing namespace std; int main() { const int a = 10; auto b = &a; auto* c = &a; auto& d = a; cout << typeid(b).name() << endl; cout << typeid(c).name() << endl; cout << typeid(d).name() << endl; return 0; }
运行结果
不过这里要注意auto*的意思自己是个指针,所以要求右边也是一个指针。
2.一行定义多个变量
3.auto不能作为函数的参数
4.auto不能直接用来声明数组
我们先回顾一下c或者c++ for的用法,再来了解下c++11的区别
代码
#includeusing namespace std; int main() { int a[] = { 1,2,3,4,5,6,7,8,9,10}; for (int i = 0; i < sizeof(a) / sizeof(int); i++) { a[i] *= 2; } for (int i = 0; i < sizeof(a) / sizeof(int); i++) { cout << a[i] << " "; } cout << endl; return 0; }
运行结果
c++11的写法范围for
int main()
{
int a[] = { 1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < sizeof(a) / sizeof(int); i++)
{
a[i] *= 2;
}
for (auto e : a)
{
cout << e << " ";
}
return 0;
}
运行结果
是不是很简单快捷,其实auto的最大的作用就是偷懒,不用写那么多代码
我们打算把数组回复到原来的样子
图片
可以看到根本没有变化,跟没加那行代码一样
其实这里是因为e是数组a的临时拷贝,你对临时拷贝做变化会印象到数组a吗?
答案是不能的
那么我们要怎么解决这个问题,我们可以用引用来解决
代码
#includeusing namespace std; int main() { int a[] = { 1,2,3,4,5,6,7,8,9,10}; for (int i = 0; i < sizeof(a) / sizeof(int); i++) { a[i] *= 2; } for (int i = 0; i < sizeof(a) / sizeof(int); i++) { cout << a[i] << " "; } cout << endl; for (auto& e : a) { e/=2; } for (auto e : a) { cout << e << " "; } return 0; }
运行结果
因为这里用了引用e是a的别名,对a的别名改变,也会对a这个数组做改变
还有一个小细节范围for不是必须要求用auto的也可以用其他类型
不过当然基本都是习惯用auto的,因为这样不管是什么类型都能实现,比较统一,e这个名字也可以变成其他的,因为它是变量名
下面这种场景是不能使用范围for的
为什么不能使用,因为用范围for必须是数组的大小,而上面图片不是,c为了考虑传参的时候不能传数组,而是传指针
还有一个问题为什么auto不能做返回值,其实如果强行做返回值也可以做
但是为什么没有这么做呢?
因为你写完一个函数返回参数的时候返回了一个auto,那么你使用这个函数的时候传什么类型?
2.nullptrnullptr就是c++里面的指针空值
以下都是赋予空指针的写法
#includeusing namespace std; int main() { int* p1 = NULL; int* p2 = nullptr; int* p3 = 0; return 0; }
这三种大多时候基本没区别,但是这里推荐用第二种p2
为什么推荐用p2因为p1和p3其实是一样的,因为它们都是宏来的
NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
但是是宏又怎么样?不一样能用吗?也没看到啥缺点啊
接下来我们不看上面的宏来看下面的代码
void f(int)
{
cout << "f(int)" << endl;
}
void f(int*)
{
cout << "f(int*)" << endl;
}
int main()
{
f(0);
f(NULL);
return 0;
}
如果没看到那个宏,f(NULL)都会觉得打印的是f(int*)吧
这就是缺点,不够规范
nullptr是没问题的
这里还有一个注意的,这是c++才会这样,c语言不是一样的
可以看到c语言不是直接替换成0的而是真的是指针来的



