NULL和nullptr的区别与联系

1、空指针,null pointer,不指向任何对象,在试图使用一个指针之前必须要检查这个指针是不是空指针。

2、举例子:

int *p1=nullptr;     等价于: int *p1=0;    // 直接将 p1 初始化为字面值常量 nullptr 或者 字面值常量 0。

int *p2=NULL;      等价于:int *p2=0;

int *p3=0;           

3、NULL 是一个预处理器变量,在头文件 cstdlib 中定义为 0 值。预处理器是运行在编译过程之前的一段程序,预处理变量不属于命名空间 std,它是由预处理器负责管理。当用到一个预处理变量时,在编译时,预处理器会自动把它替换为实际值,因此使用 NULL 初始化指针和使用 0 初始化指针是一样的。

nullptr 是一个字面值常量,它可以被转化为任何其他类型的指针。

另外,把int 型变量直接赋值给指针是错误的操作,即使int 型变量等于0 也不行!

int zero=0;    int *p=zero;    (错误,不能把int 型变量直接赋值给指针!)


1、测试1:

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3. void go(int num)  
  4.     cout<<"go num"<<endl;  
  5. void go(char *p)  
  6.     cout"go p"<<endl;  
  7. void main()  
  8. {  
  9.     void *p=NULL;  
  10.     go(p);         //error: “go”: p 的类型不能转换为这 2个重载函数中任意一个函数的形参类型。  
  11. }  

2、测试2:(  NULL是0。nullptr是空指针void*。)

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3. void go(int num)  
  4.     cout<<"go num"<<endl;  
  5. void go(void *p)  
  6.     cout<<"go p"<<endl;  
  7. int main()  
  8. {  
  9.     void *p = NULL;  
  10.     go(p);         //go p  
  11.     go(NULL);      //go num  
  12.     go(nullptr);   //go p  
  13.     system("pause");  
  14.     return 0;  
  15. }  

3、在强调一下,NULL 在C++中的定义仅仅是 0,仅此而已。

4、参考:http://www.cnblogs.com/malecrab/p/5569707.html

(1)引出话题:

有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;

也有人直接使用0值作为空指针常量,例如:int* p = 0;

前者可能觉得:NULL作为空指针常量,名字很形象,可读性较强。后者可能觉得:NULL并不是C/C++语言的关键字,而是一个在

标准库头文件<stddef.h>中定义的宏,因此要使用NULL,可能需要直接或简介地包含<stddef.h>头文件,比较麻烦。

(2)NULL是一个宏,在C/C++标准中,它的值只一个空指针常量(null pointer constant)。

而在C语言中,常数0 和(void *)0 都是空指针常量。C++中(暂且忽略C++11新标准),常数0 是,但(void *)0 不是。

以GCC的宏定义为例:

[cpp]  view plain  copy
  1. #if defined(__cplusplus)  
  2. # define NULL 0    // C++中使用0作为NULL的值  
  3. #else  
  4. # define NULL ((void *)0)    // C中使用((void *)0)作为NULL的值  
  5. #endif  

(3)为什么C 中 (void*)0 是空指针常量,而C++中不是?
答:因为C 语言中任何类型的指针都可以(隐式地)转换为 void* 型,反过来也行。
而C++ 中void* 型不能隐式地转换为别的类型指针(例如:int  *p = (void *) 0;  使用C++编译器编译会报错)。
既然C/C++标准中,常数0 都可作为空指针常量,为什么不统一使用0?
答:个人觉得由于(void*)0 更能体现指针的意义,而常数0 更多的时候是用作整数。
因此,C语言中NULL 定义选择了(void *) 0。(仅供参考)

(4)C++11中为什么要引入nullptr?

考虑着这样一个函数重载的情形:

[cpp]  view plain  copy
  1. #include <stddef.h>  
  2. void foo(int) {}     // #1  
  3. void foo(char*) {}   // #2  
  4. int main()  
  5.  {  
  6.     foo(NULL); // 调用#1还是#2?  
  7.     return 0;  
  8. }  

从字面上来讲,NULL是个空指针常量,我们可能会觉得:既然是个指针,那么应该调用#2。但事实上调用的却是#1,因为C++中NULL扩展为常数0,它是int型。
根本原因就是:常数0既是整数常量,也是空指针常量。
为了解决这种二义性,C++11标准引入了关键字nullptr,它作为一种空指针常量。

[cpp]  view plain  copy
  1. void foo(int) {}     // #1  
  2. void foo(char*) {}   // #2  
  3. int main()  
  4. {  
  5.     foo(nullptr); // 它会毫无异议地调用#2  
  6.     return 0;  
  7. }  

[cpp]  view plain  copy
  1. 再简化一点就是  
  2. void f(int i){  
  3. cout << "take integer" << endl;  
  4. }  
  5. void f(int *p){  
  6. cout << "take pointer" << endl;  
  7. }  
  8.   
  9. 调用f(NULL)  
  10. gcc编译会提示重载歧义  
  11. 调用f(nullptr)一切正常  


 结论:  如果使用 nullptr 初始化对象,就能避免 0 指针的二义性的问题。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安塔利亚的猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值