C++中NULL与nullptr的区别小结

 更新时间:2025年07月07日 11:30:30   作者:Jammingpro  
本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

C++98空值——NULL

在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现
不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下
方式对其进行初始化:👇

int* p = NULL;

NULL实际上就是宏,在C头文件stddef.h中可以看到关于NULL的定义👇

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

可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何
种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:

程序本意是想通过func(NULL)调用指针版本的func(int*)函数,但是由于NULL被定义成0,因此与程序的初衷相悖。
在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器
默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void
*)0。

C++11空值——nullptr

既然使用NULL存在问题,那么就一定会有其他方式替换它。那就是nullptr。底层原理上,nullptr 在编译时会被翻译为一个空指针常量的特殊值。这个特殊的值可以根据编译器的实现而有所不同,但它通常被定义为被解引用时不引发错误的值
一句话总结:nullptr更安全,不会出现引发不必要的错误。
nullptr注意事项:
1.在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入
的。
2. 在C++11中,sizeof(nullptr)sizeof((void*)0)所占的字节数相同。
3.为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr

区别对比

特性NULLnullptr
引入版本C 和早期的 C++C++11
定义宏,通常定义为 #define NULL 0关键字,类型为 std::nullptr_t
类型整数常量,通常是 int专用类型 std::nullptr_t
指针转换可隐式转换为指针类型,但可能引起歧义可隐式转换为任何指针类型,无歧义
整数转换是一个整数,参与整数运算不是整数,不能参与整数运算
安全性易引起类型混淆,存在潜在的歧义问题类型安全,避免了指针和整数混淆的问题
适用性向后兼容的代码,旧式 C++ 项目现代 C++ 编程,推荐使用

示例 

展示了 nullptr 和 NULL 的不同效果:

#include <iostream>
using namespace std;

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

void func(void*) {
    cout << "func(void*) called" << endl;
}

int main() {
    func(NULL);    // 输出:func(int) called,因为 NULL 是整数类型
    func(nullptr); // 输出:func(void*) called,因为 nullptr 是空指针类型

    // 类型检查
    int* p1 = NULL;       // 合法,NULL 转换为 int*
    // int val = nullptr; // 错误,nullptr 不能隐式转换为 int
    int* p2 = nullptr;    // 合法,nullptr 是类型安全的空指针

    return 0;
}

到此这篇关于C++中NULL与nullptr的区别小结的文章就介绍到这了,更多相关C++ NULL与nullptr内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Qt采用线程以队列方式实现下发数据

    Qt采用线程以队列方式实现下发数据

    在C++中队列是一种常用的数据结构之一,一种特殊的线性表,一般采用先进先出的方式。本文主要为大家介绍了Qt如何以队列方式实现下发数据,感兴趣的可以了解一下
    2022-10-10
  • 你真的懂C++中的namespace用法

    你真的懂C++中的namespace用法

    命名空间(namespace)为防止名字冲突提供了更加可控的机制,命名空间分割了全局命名空间,其中每个命名空间是一个作用域,今天通过本文给大家分享C++中namespace用法,感兴趣的朋友一起看看吧
    2021-06-06
  • C语言实战之纸牌游戏

    C语言实战之纸牌游戏

    这篇文章主要为大家介绍了通过C语言实现的纸牌游戏的示例代码,文中的示例代码讲解详细,对我们学习C语言有一定的帮助,感兴趣的小伙伴可以跟随小编学习一下
    2021-12-12
  • 用C++实现推箱子

    用C++实现推箱子

    这篇文章主要为大家详细介绍了用C++实现推箱子,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • 如何在程序中判断VS的版本(实现方法详解)

    如何在程序中判断VS的版本(实现方法详解)

    下面小编就为大家带来一篇如何在程序中判断VS的版本(实现方法详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • C语言深入探究栈的原理

    C语言深入探究栈的原理

    一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则
    2021-11-11
  • C++中的friend友元函数详细解析

    C++中的friend友元函数详细解析

    友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
    2013-09-09
  • C++全面细致讲解复数类

    C++全面细致讲解复数类

    本文章向大家介绍C++ 标准库中的复数类,主要包括C++ 标准库中的复数类使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下
    2022-06-06
  • C语言链表实现商品库存管理系统

    C语言链表实现商品库存管理系统

    这篇文章主要为大家详细介绍了C语言链表实现商品库存管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C++ 将字符串值赋给CHAR数组的实现

    C++ 将字符串值赋给CHAR数组的实现

    这篇文章主要介绍了C++ 将字符串值赋给CHAR数组的实现,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01

最新评论