前言

在C语言中,我们常常用NULL作为指针变量的初始值,而在C++中,却不建议你这么做。

NULL是什么

在《NULL,0,'\0',"0","\0"的区别》一文中,我们已经知道了在C中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++和C中不一样呢?因为C++中不能将void *类型的指针隐式转换成其他指针类型,从下面的例子可以看出来:

//null.cpp
#include<iostream>
int main(void)
{char p[] = "12345";int *a = (void*)p;return 0;
}

编译:

$ g+ -o null null.cpp
null.cpp: In function 'int main()':
null.cpp:5:17: error: invalid conversion from 'void*' to 'int*' [-fpermissive]int *a =(void*)p;

所以不能将NULL定义为(void*)0。

nullptr

nullptr并非整型类别,甚至也不是指针类型,但是能转换成任意指针类型。nullptr的实际类型是std:nullptr_t。

为什么该使用nullptr

回到最开始的问题,为什么作为指针的语义,我们应该使用nullptr,而不是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:16:14: error: call of overloaded ‘test(NULL)’ is ambiguoustest(NULL);

很不幸,编译报错了,提示我们有二义性,按照《重载函数匹配规则》,两个都可以匹配,因此最终报错。

但是如果我们使用nullptr却不会:

test(nullptr);

除了这点之外,在C++模板中它还有更好的表现。 看下面的代码:

#include<iostream>
using namespace std;
template<typename Type1,typename ptrType>
void test(Type1 fun,ptrType ptr)
{/*do something*/fun(ptr);return;
}
void fun(int *val)
{cout<<"fun"<<endl;
}
int main(void)
{test(fun,NULL);return 0;
}

编译报错了:

main.cpp:8:8: error: invalid conversion from ‘long int’ to ‘int*’ [-fpermissive]fun(ptr);

很显然NULL被推导为long int,而不是空指针,因而导致函数类型不匹配而报错。

但是如果我们用nullptr就不会有上面的问题。

总结

如果你想表示空指针,那么使用nullptr,而不是NULL。

注:nullptr在C++ 11中才出现。

转载自https://cloud.tencent.com/developer/article/1494848

nullptr与NULL的区别相关推荐

  1. C++ NULL nullptr和0的区别

    C中的NULL 在C语言中我们将NULL用作空指针之用,NULL在C语言中的定义如下: #define NULL ((void *)0) 可以看到,C语言中NULL是一个void*指针,我们常用其来对 ...

  2. c语言null和nullptr,nullptr和NULL

    nullptr是c++11中的关键字,表示空指针 要区分nullptr和NULL,首先要明白NULL的含义: NULL是一个宏定义,在c和c++中的定义不同,c中NULL为(void*)0,而c++中 ...

  3. iOS——nil、Nil、NULL和[NSNull null]的区别

    iOS--nil.Nil.NULL和[NSNull null]的区别 首先我们先来看一下苹果文档上的解释: nil:Defines the id of a null instance.(定义空实例的i ...

  4. mysql 中is not null 和 !=null的区别

    今天做定时任务,需要用到一个mysql查询 于是我就写: sqlcondition=" and fplsh!=null and iskp='2'" 却发现发挥的list为空 很是诧 ...

  5. mysql''和null,mysql中NULL和null的区别

    接触php的web开发一段时间了,在进行数据库操作的时候经常会遇到一个问题,使得同一字段在页面显示时有3种类型NULL,null以及数字,当时的解决办法是将这一字段定义为varchar类型,在插入数据 ...

  6. nullptr和NULL

    nullptr是c++11中的关键字,表示空指针 要区分nullptr和NULL,首先要明白NULL的含义: NULL是一个宏定义,在c和c++中的定义不同,c中NULL为(void*)0,而c++中 ...

  7. JS-undefined与null的区别

    JS-undefined与null的区别 var array = new Array(); array[0] = 1; array[1] = 2; array[10] =10; array[2]到ar ...

  8. 关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别

    一.背景 根据业务需求,发现以前的同事在设计表的时候,很多字段都没有设置默认值.在mysql5.7版本之后,没有设定默认值的字段,在严格模式下是很容易报错的,所以我这边需要先给每个字段加上一个默认值. ...

  9. mysql char null_关于mysql设置varchar 字段的默认值''和null的区别,以及varchar和char的区别...

    一.背景 根据业务需求,发现以前的同事在设计表的时候,很多字段都没有设置默认值.在mysql5.7版本之后,没有设定默认值的字段,在严格模式下是很容易报错的,所以我这边需要先给每个字段加上一个默认值. ...

最新文章

  1. RISC-V会被卡吗?那么你觉得C语言会不会被卡? | 包云岗
  2. eeglab教程系列(13)-学习和删除ICA组件
  3. 相对路径转成绝对路径
  4. Linux top 使用技巧
  5. CodeVs天梯白银Silver题解
  6. 061 实例15-霍兰德人格分析雷达图
  7. CANOPEN 学习(一) CANFestival 字典工具 环境搭建
  8. vue json对象转数组_如何使用Vue.js渲染JSON中定义的动态组件
  9. iview 循环 卡片 更好图标 背景色 标题
  10. 国家2000坐标系的理解
  11. PostgreSQL数据库——Pigsty grafana Ansible
  12. 基于低代码平台的OA系统,更灵活高效!
  13. echarts(雷达图和中国地图)
  14. 有关于fprintf()函数的用法
  15. 搭建Prometheus+Grafana实时监控平台监控Java应用服务
  16. 12306之余票查询流程解析
  17. github:master提交项目到远程仓库出现“There isn’t anything to compare.”
  18. 如何使用 JavaScript 构建计算器应用程序
  19. WPS画报的电脑壁纸怎么下载
  20. Java之环境变量配置

热门文章

  1. 计算机组成原理——辅助存储器
  2. 【网络基础系列二】BOOTP、DHCP协议
  3. 【引用】安卓巴士精选Android开发教程
  4. 计算器算贝塞尔公式_怪物猎人:近战技能收益计算器Ver.4打死不改版
  5. 【毕业设计】ESP32单片机疫情防交叉感染洗手液分配系统 -物联网 嵌入式
  6. 红枣的功效与食用方法
  7. linux 终端 mosh,使用Mosh来优化SSH连接
  8. 错误解决: java.lang.SecurityException: Permission Denial
  9. 居于WEB的视频会议系统介绍(Web Video Conference System)
  10. 6.2 、MyBatis 高级映射(resultMap 标签多表联查 , 一对多,多对一关系)