1.auto
1.auto的作用
1.C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得 什么意思呢?看代码
#include<iostream>
using 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可以和指针和引用一起使用 代码
#include<iostream>
using 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不能直接用来声明数组
3.auto的实用场景
我们先回顾一下c或者c++ for的用法,再来了解下c++11的区别 代码
#include<iostream>
using 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吗? 答案是不能的 那么我们要怎么解决这个问题,我们可以用引用来解决
代码
#include<iostream>
using 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.nullptr
nullptr就是c++里面的指针空值 以下都是赋予空指针的写法
#include<iostream>
using 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的而是真的是指针来的
|