auto(c++11)和nullptr(c++11)

c++11是继c++98后的下一个大版本,c++11在vs编译器中是vs2011以后的版本支持,以前的版本支持的不全。

auto(c++11)

auto关键字在c/c++中就有,即auto修饰的变量是具有自动储存器的局部变量,但是没人去用。

因为auto关键字是局部变量前自动补充的。

C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

简单来说就是auto修饰的变量是什么类型的,由给它赋值的变量决定。

int add()

{

    return 1;

}

……

int a = 10;

auto b = a;//b的类型为int型

auto c = 'a';//c的类型为char类型

auto d = add();//d的类型为add函数的返回类型

auto的这个过程叫自动推导。

auto修饰变量必须初始化

auto的这个用法只有在支持c++11的编译器上才可以用,不支持c++11的编译器会报错

下面介绍一个可能有用的函数,可以看变量的类型(包括自定义类型)。

cout << typeid(b).name() << endl;

cout << typeid(c).name() << endl;

cout << typeid(d).name() << endl;

这是一个用法,记住就行。

打印出:

int

char

int

下面讲解auto的一些比较奇葩的用处

int x = 10;

auto a = &x;

auto* b = &x;//auto加*,代表自动推导的变量必须是地址,传变量会报错

auto& d = x;

cout << typeid(a).name() << endl;

cout << typeid(b).name() << endl;

cout << typeid(c).name() << endl;

结果打印出:

int *//int a前加上const,打印出来的是int const*,int const*和const int*是等价的,不同的是int* const

int *

int

auto定义多行变量:

如果出现auto a = 10, b = 200; 这种情况,推导的变量必须为同种类型的变量

如果这样:auto a = 10, b = 'a'; 就会编译失败。因为auto最终还是要被编译器替换为某个具体的变量类型的。

使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型

auto的实际价值:

1.在c++高阶数据结构的容器中简化代码,说的简单一点就是类型很长时就使用auto,交给编译器自动推导。

    这个简化代码和typedef存在不同。

2.循环改进方面

void TestFor()

{

    int array[] = { 1, 2, 3, 4, 5 };

    for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)

        array[i] *= 2;

    for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)

        cout << *p << " ";

    cout << endl;

}

这是C语言和c++98版本的打印方式

在c++11版本中,可以实现一个叫范围for的用法,针对循环方式进行简化:

void TestFor()

{

    int array[] = { 1, 2, 3, 4, 5 };

    for(auto e : array)//实现原理:依次自动取array中的内容赋值给e,自动结束。e是变量名,可以随意取。

    {

        cout << e << " ";

    }

    cout << endl;

}

这样可以打印出数组array中的数据,即使array中数据增加也可以正常打印。

e只是array中数据的拷贝,对e的改变不会影响数组array中的数据。即:

for(auto e : array)

{

    e /= 2;

}

不会导致array中的数据改变。需要对array中数据进行修改的话,需要使用引用

for(auto& e : array)

{

    e /= 2;

}

范围for不是一定要用auto实现,指明具体类型也可以实现,比如将上面代码的auto部分替换成int,也可以正常打印。只是范围for习惯使用auto。

范围for,冒号(:)后面必须是数组名,不能用指针。所以这种情况是不能使用的。

void printArr(int arr[])//数组传参后,形参就是指针了//这种情况不行!

{

    for(int  e : arr)

    {

        cout << e << " ";

    }

    cout << endl;

}

auto不能应用的情况:

1. 不能作函数参数 (缺省参数也不行) 

2.不能作返回值 //在对特定类型的数据进行处理时,参数类型和返回值类型如果为auto,使用时就不知道传什么样的参数了。

3.不能声明数组  //即这种情况auto b[] = {1 ,2, 3};

nullptr(c++11)

nullptr是c++11中新增的关键字,代表空指针。也就是说指针置空有三种方式。

int* p1 = NULL;

int* p2 = nullptr;

int* p3 = 0;

一般情况下三种是一样的,但是c++中推荐使用nullptr。NULL和0的赋值方式,严格来讲是不规范的。

原因: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);//会调用第一个函数,因为NULL是宏,预处理时被替换成了0,但是NULL想表达的是指针类型

    f((int*)NULL);

    return 0;

}

c++11为了补这个坑,就定义了nullptr,指((void*)0)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值