IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 一文搞懂 NULL 和 nullptr 的区别【C/C++面试必备】 -> 正文阅读

[C++知识库]一文搞懂 NULL 和 nullptr 的区别【C/C++面试必备】

作者: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 <iostream>
using namespace std;

void func(int x) {
    cout<<"void func(int x)"<<endl;
}

void func(char *y) {
    cout<<"void func(int *y)"<<endl;
}

int main()
{
    func(NULL);
    return 0;
}

编译结果为:

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 <iostream>
using namespace std;

void func(int x) {
    cout<<"void func(int x)"<<endl;
}

void func(char *y) {
    cout<<"void func(int *y)"<<endl;
}

int main()
{
    func(nullptr);
    return 0;
}

输出结果为:

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 <stdio.h> 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 <stddef.h> 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 >= 201103L
#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/1282295/what-exactly-is-nullptr/1283623#1283623

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

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

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-07 11:40:49  更:2021-07-07 11:41:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 5:48:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码