C++中NULL和nullptr的区别

C++中NULL和nullptr的区别在编写 C 程序的时候只看到过 NULL 而在 C 的编程中 我们可以看到 NULL 和 nullptr 两种关键字 其实 nullptr 是 C 11 版本中新加入的 它的出现是为了解决 NULL 表示空指针在 C 中具有二义性的问题 为了弄明白这个问题 我查找了一些资料 总结如下 一 C 程序中的 NULL 在 C 语言中 NULL 通常被定义为 defineNULL void 0 所以说 NULL 实际上是

在编写C程序的时候只看到过NULL,而在C++的编程中,我们可以看到NULL和nullptr两种关键字,其实nullptr是C++11版本中新加入的,它的出现是为了解决NULL表示空指针在C++中具有二义性的问题,为了弄明白这个问题,我查找了一些资料,总结如下。

一、C程序中的NULL

在C语言中,NULL通常被定义为:#define NULL ((void *)0)

所以说NULL实际上是一个空指针,如果在C语言中写入以下代码,编译是没有问题的,因为在C语言中把空指针赋给int和char指针的时候,发生了隐式类型转换,把void指针转换成了相应类型的指针。

int *pi = NULL; char *pc = NULL;

二、C++程序中的NULL

但是问题来了,以上代码如果使用C++编译器来编译则是会出错的,因为C++是强类型语言,void*是不能隐式转换成其他类型的指针的,所以实际上编译器提供的头文件做了相应的处理:

#ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif

可见,在C++中,NULL实际上是0.因为C++中不能把void*类型的指针隐式转换成其他类型的指针,所以为了结果空指针的表示问题,C++引入了0来表示空指针,这样就有了上述代码中的NULL宏定义。

但是实际上,用NULL代替0表示空指针在函数重载时会出现问题,程序执行的结果会与我们的想法不同,举例如下:

#include 
  
    using namespace std; void func(void* i) { cout << "func1" << endl; } void func(int i) { cout << "func2" << endl; } void main(int argc,char* argv[]) { func(NULL); func(nullptr); getchar(); } 
  

  C++中NULL和nullptr的区别

在这段代码中,我们对函数func进行可重载,参数分别是void*类型和int类型,但是运行结果却与我们使用NULL的初衷是相违背的,因为我们本来是想用NULL来代替空指针,但是在将NULL输入到函数中时,它却选择了int形参这个函数版本,所以是有问题的,这就是用NULL代替空指针在C++程序中的二义性。

三、C++中的nullptr

为解决NULL代指空指针存在的二义性问题,在C++11版本(2011年发布)中特意引入了nullptr这一新的关键字来代指空指针,从上面的例子中我们可以看到,使用nullptr作为实参,确实选择了正确的以void*作为形参的函数版本。

总结:

NULL在C++中就是0,这是因为在C++中void* 类型是不允许隐式转换成其他类型的,所以之前C++中用0来代表空指针,但是在重载整形的情况下,会出现上述的问题。所以,C++11加入了nullptr,可以保证在任何情况下都代表空指针,而不会出现上述的情况,因此,建议以后还是都用nullptr替代NULL吧,而NULL就当做0使用。

其他:在没有C++ 11的nullptr的时候,我们怎么解决避免这个问题呢?

const class nullptr_t { public: template 
  
    inline operator T*() const { return 0; } template 
   
     inline operator T C::*() const { return 0; } private: void operator&() const; } nullptr = {}; 
    
  

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/199776.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 下午12:14
下一篇 2026年3月20日 下午12:14


相关推荐

  • oracle导出错误904,exp 导出 EXP-00056: 遇到 ORACLE 错误 904

    oracle导出错误904,exp 导出 EXP-00056: 遇到 ORACLE 错误 904同一台机器上,其中一个备份正常<1>,另外一个报错<2>。同一台机器上导出日志显示的版本居然不一样,哪个高人给指点下。我机器上装的是Oracle9iEnterpriseEditionRelease9.2.0.8.0-Production(client)<1>连接到:Oracle9iEnterpriseEditionRelease9.2…

    2026年1月30日
    4
  • Spring常用注解(绝对经典)

    Spring常用注解(绝对经典)最近在看 B 站颜群老师的课程 Javaweb gt spring gt springMVC gt mybatis gt spring 高级 一路走来 跌跌撞撞 发现 spring 也不过尔尔 说白了 spring 就是想尽办法将 new 做的更简单 更完美 更可配置 Spring 的一个核心功能是 IOC 就是将 Bean 初始化加载到容器中 Bean 是如何加载到容器的 可以使用 Spring 注解方式或者 SpringXML 配置方式 Spring 注解方式减少了配置文件内容 更加便于管理 并且使用注解可以大大提高了开发效

    2026年3月20日
    2
  • VGGNet网络结构

    VGGNet网络结构深度神经网络一般由卷积部分和全连接部分构成 卷积部分一般包含卷积 可以有多个不同尺寸的核级联组成 池化 Dropout 等 其中 Dropout 层必须放在池化之后 全连接部分一般最多包含 2 到 3 个全连接 最后通过 Softmax 得到分类结果 由于全连接层参数量大 现在倾向于尽可能的少用或者不用全连接层 神经网络的发展趋势是考虑使用更小的过滤器 如 1 1 3 3 等 网络的深度更深 2012 年 AlenNet

    2026年3月26日
    2
  • SpringBoot全局配置long转String 丢失精度[通俗易懂]

    SpringBoot全局配置long转String 丢失精度[通俗易懂]web项目中,Java后端传过来的Long/long类型,前端JS接收会丢失精度。 **本文推荐第三、第四种方式**第一种方式简单粗暴,将所有的Lang类型,改为String,数据库改成varchar类型;第二种方式自己建个配置类extendsWebMvcConfigurerAdapter已经被弃用,直接实现WebMvcConfigurer该接口就行了@EnableWebMvc@ConfigurationpublicclassWebDataConvertConfigimple

    2022年5月15日
    41
  • 电脑开机读不到固态硬盘怎么办_电脑读不到固态硬盘怎么办

    电脑开机读不到固态硬盘怎么办_电脑读不到固态硬盘怎么办电脑重启后发现电脑检测不出固态硬盘,这种情况大家不要慌张,下面就由学习啦小编跟大家分享电脑重启后读不到固态硬盘该怎么办,欢迎大家来阅读学习。电脑重启后读不到固态硬盘怎么办方法一1、首先进入BIOS后,选择“IDEHDDAutoDetection”项目,看是否可以检测到硬盘的存在,并核对型号是否一致,如果正常排除硬件问题,如果还不能找到硬盘,那么就是您的硬盘损坏或连接不正确。2、如果在bios…

    2025年11月19日
    9
  • d3火山图入门

    d3火山图入门要做一个基础火山图 需求如图 前端用 vue 数据端用 node 对本地文件进行读操作将文件内容传给前端 首先在项目中引入 d3 npminstallsa 4 7 1 复制代码在需要用到 d3 的 vue 文件下引入 import asd3from d3 复制代码 html 代码如下 lt divid canvas gt lt div gt 复制代码下面咱开始画图啦 1 在

    2026年3月26日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号