一文搞懂 NULL 和 nullptr 的区别【C/C++面试必备】

一文搞懂 NULL 和 nullptr 的区别【C/C++面试必备】作者 Linux 猿 CSDN 博客专家 Linux C C 面试 刷题 算法尽管咨询我 关注我 有问题私聊 大家可能对 NULL 和 nullptr 都有了解 NULL 最开始是在 C 语言中使用 后来 C 11 引入了 nullptr 为什么 C 11 要引入 nullptr 呢 那一定是 NULL 在某些方面存在哪些不足 所以引入了 nullptr 下面我们来看一下 本文使用的环境是 系统环境 Ubuntu20 04 开发工具 VisualStudio

作者:Linux猿

 CSDN博客专家,C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

 大家可能对 NULL 和 nullptr 都有了解,NULL属于 C 语言中的宏,后来 C++11 引入了 nullptr 关键字,都用来表示空指针。

那问题来了,为什么 C++11 要引入 nullptr 呢?

那必定是 NULL 在某些方面存在某些不足,所以引入了nullptr,下面我们来看一下!

本文使用的环境:

系统环境:Ubuntu 20.04 

开发工具:Visual Studio Code 1.57.1

在 C 语言中,NULL是一个宏,被定义为空指针,定义形式如下所示:

#define NULL ((void *)0)

 我们来看一个 C++ 中使用 NULL 的例子,代码如下所示:

#include 
  
    using namespace std; void func(int x) { cout<<"void func(int x)"< 
    
  

编译结果为:

linuxy@linuxy:~/dirNULL$ g++ main.cpp -o main main.cpp: In function ‘int main()’: main.cpp:14:14: error: call of overloaded ‘func(NULL)’ is ambiguous 14 | func(NULL); | ^ main.cpp:4:6: note: candidate: ‘void func(int)’ 4 | void func(int x) { | ^~~~ main.cpp:8:6: note: candidate: ‘void func(char*)’ 8 | void func(char *y) { | ^~~~ linuxy@linuxy:~/dirNULL$

从编译结果来看,显示程序有二义性,程序提示 func(NULL) 有两个可选项。

先解释下上面的 C++ 程序:程序中重载了函数 func,可根据参数不同分别进行调用。但是存在一个问题,C语言是有隐式类型转换的,所以 NULL(这里实际上是 (void *)0 ) 可以隐式转换到 int 或 char * 。这就让程序很为难了,程序不知道选择调用哪个函数。而在 C 语言中,并不支持函数重载,故在纯 C 语言中不会有上面这个问题。

下面我们来修改一下上面的程序,将 NULL 替换为 nullptr,修改后如下所示:

#include 
  
    using namespace std; void func(int x) { cout<<"void func(int x)"< 
    
  

输出结果为:

linuxy@linuxy:~/dirNULL$ g++ main.cpp -o main linuxy@linuxy:~/dirNULL$ ./main void func(int *y) linuxy@linuxy:~/dirNULL$

编译通过,并且执行成功!

看到这里你应该明白为什么 C++11 引入 nullptr 了吧!

就是因为 NULL 在 C++ 程序中容易引起二义性!

下面来看下 nullptr 的具体内容。

在 stddef.h 文件中,NULL 的定义如下:

/* A null pointer constant. */ #if defined (_STDDEF_H) || defined (__need_NULL) #undef NULL /* in case 
  
    has defined it. */ #ifdef __GNUG__ #define NULL __null #else /* G++ */ #ifndef __cplusplus #define NULL ((void *)0) #else /* C++ */ #define NULL 0 #endif /* C++ */ #endif /* G++ */ #endif /* NULL not defined and 
   
     or need NULL. */ #undef __need_NULL 
    
  

先解释一下上面几个宏的含义:

__GNUG__ :GNU C++ 编译器对此进行了定义,等同于(__GNUC__ && __cplusplus);

__null :它是 g++ 内部定义的,用途与 C++11 中添加的标准 nullptr 基本相同,充当指针,而不是整数;

__cplusplus :C++ 预处理器宏;

在上文第一个例子中,NULL 使用的是 __null,即:((void*)0)(不同的编译器可能会有所差别)。但是,建议在想表示指针的地方使用 nullptr。尽量不同 __null,因为它仅在 GNU 编译器下定义,影响可移植性。

另外,NULL 在 C++ 中被定义为 0,也应尽量少用 NULL。

在 stddef.h 中,nullptr 的定义如下:

#if defined(__cplusplus) && __cplusplus >= L #ifndef _GXX_NULLPTR_T #define _GXX_NULLPTR_T typedef decltype(nullptr) nullptr_t; #endif #endif /* C++11. */

在上面的定义中,nullptr_t 是 decltype(nullptr) 的别名,而 nullptr 是一个空指针常量类型,但并没有实际的类型名称。

总结

在 C++ 中表示指针的地方,使用 nullptr 表示空指针。尽量不使用 NULL 和 __null。

参考文献:

[1] https://stackoverflow.com/questions//what-exactly-is-nullptr/#

[2] https://stackoverflow.com/questions//null-vs-nullptr-why-was-it-replaced

[3] https://en.cppreference.com/w/cpp/types/nullptr_t

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

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

(0)
上一篇 2026年3月19日 下午3:08
下一篇 2026年3月19日 下午3:08


相关推荐

发表回复

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

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