C++中NULL和nullptr的区别

前言

C和C++的变量名是对大小写敏感的,因此NULL和null并不是一回事,前者是C/C++中的系统关键字,null并不是。C++11以后又引入了nullptr,用以解决NULL在隐式转换和作为函数传入参数时的二义性问题。

在C++11以前,在C/C++语言中,我们常常用NULL作为指针变量的初始值。而在C++11之后,却不建议你这么做。
其实NULL根据命名全大写可以看出来,它是一个常量,既然是常量,就需要进行宏定义。C语言的标准头文件是这样定义的

 #define NULL ((void*)0)

而到了C++中,则变成了

#define NULL 0

查阅stddef.h,可以看到如下定义

#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif

从定义中可以看出,C++中,NULL其实就是0,但是也可以用作空指针,只是用作空指针可能是为了兼容C,迫于无奈。
以下一段代码可以很好地解释NULL存在的问题:

#include<iostream>
using namespace std;
void test(void *p)
{
    cout<<"p is pointer "<<p<<endl;
 }
void test(int num)
{
    cout<<"num is int "<<num<<endl; 
}
int main(void)
{
    test(NULL);
    return 0; 
}

这时,如果编译的话,会报以下错误,

$ g++ -o test test.cpp
    main.cpp: In function ‘int main()’:
    main.cpp:14:14: error: call of overloaded ‘test(NULL)’ is ambiguous
         test(NULL);

很明显,NULL存在二义性,它既是整数,也是一个指针,函数test()无法根据参数的数据类型判断应该调用哪一个实现。
这时使用nullptr的优越性就体现出来了,因为它可以很好地把空指针这一层意思给剥离出来。nullptr就是C++11为了解决这个痛点而推出的东西。

    test(nullptr);

就会自然而然地走到指针的那个函数里。因此,以后若想使用整数特性,就赋值为0,若想使用指针特性,就赋值为nullptr,这样一目了然,减少了未知的Bug的可能性。
多说一句,为什么要作此改动,我想首先应该是C和C++在处理void 类型的时候存在一定的区别。C语言中,void 类型的变量可以赋值给任意类型的指针,也可以被任意类型的指针赋值,两个方向都不会报错。但是C++具有更严格的类型检查,前者是不被允许的。
因此下面一段C语言代码是可以编译通过的

int main()
{
    void* a;
    int* b=a;
}

但是下面的C++代码就会报错

test.cpp:4:7: error: cannot initialize a variable of type 'int *' with an lvalue of type 'void *'
int* b=a;

与此同时,在malloc上,也存在类似的问题:

int len = 100;
int p = malloc(len * sizeof(int)); // C推荐做法
int p = (int )malloc(len * sizeof(int)); // C++推荐做法

malloc函数返回值得类型是 void*,C不要求强制类型转换,会自动进行隐式转换,但是C++则需要,因为void* 不能转换成其他类型的指针。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,407评论 0 6
  • 1.写一个NSString类的实现 +(id)initWithCString:(c*****t char *)nu...
    韩七夏阅读 3,813评论 2 37
  • 1 文件结构 每个C++/C程序通常分为两个文件。一个文件用于保存程序的声明(declaration),称为头文件...
    Mr希灵阅读 2,909评论 0 13
  • 冬天已然遠去,擋不住陽光的來臨。水草的柔漫,迷失不了我對燦爛的向往與追求。它必將屬於我,夢中的殿堂。因爲捨棄,才有...
    苍山林木阅读 159评论 0 1
  • "嘀嗒,嘀嗒”时间一分一秒的过去了。满怀好奇的我们坐在时光列车上听天由命的,由二十年后穿越而来的机器人任意摆...
    邓雪梅dxm阅读 240评论 0 2