当前位置: 首页 > article >正文

【C/C++】区分0、NULL和nullptr

🦄个人主页:小米里的大麦-CSDN博客

🎏所属专栏:C++_小米里的大麦的博客-CSDN博客

🎁代码托管:C++: 探索C++编程精髓,打造高效代码仓库 (gitee.com)

⚙️操作环境:Visual Studio 2022

目录

1. 0 和空指针

2. NULL

3. nullptr

总结 

共勉


在C/C++中,0NULLnullptr 都表示指针的空值,但它们有不同的语义和使用场景。

1. 0 和空指针

在C和C++98中,数字 0 常常被用作空指针的表示。因为C语言规定整型常量 0 可以隐式转换为任意类型的指针值,所以使用 0 作为空指针值是合法的。

int* p1 = 0;  // 合法,p1 是空指针

但是,使用 0 来表示空指针时,代码的可读性可维护性较差,因为 0 既可以表示数值也可以表示指针。因此C++引入了 NULL 来代替 0

2. NULL

NULL 是在C语言的标准头文件 <stddef.h> 或 C++ 的 <cstddef> 中定义的,通常定义为 ((void*)0) 或单纯的 0。在C++98中,它仍然可能会与整型 0 混淆,因为它本质上是 0

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else  /* __cplusplus */
#define NULL    ((void *)0)
#endif  /* __cplusplus */
#endif  /* NULL */

使用 NULL 来表示空指针可以提高代码的可读性,避免误将数字 0 和指针值混淆。 但因为 NULL 是宏,使用它仍然有一些潜在的问题,尤其是当函数重载涉及不同类型时。

#include <iostream>

void Fun(int p) {
    std::cout << "Fun(int)" << std::endl;
}

void Fun(int* p) {
    std::cout << "Fun(int*)" << std::endl;
}

int main() {
    Fun(0);       // 调用 Fun(int)
    Fun(NULL);    // 调用 Fun(int) 因为 NULL 被定义为 0
}
在这个例子中,Fun(NULL) 实际上调用了 Fun(int),而不是期望的 Fun(int*),因为 NULL 被解释为 0。

3. nullptr

为了解决 0NULL 的这些问题,C++11 引入了新的关键字 nullptr,这是一个明确的空指针类型,可以确保它只能用于指针上下文中。

int* p1 = nullptr;  // p1 是空指针

0NULL 不同,nullptr 是类型安全的,不能被隐式转换为其他类型(如整型)。它不会产生函数重载歧义问题,因此推荐在C++11及之后的代码中使用 nullptr

#include <iostream>

void Fun(int p) {
    std::cout << "Fun(int)" << std::endl;
}

void Fun(int* p) {
    std::cout << "Fun(int*)" << std::endl;
}

int main() {
    Fun(nullptr);  // 明确调用 Fun(int*)
}

总结 

虽然他们三者区别并不大,但是,在一些特殊情况还是需要进行区分使用的。

  • 0:C/C++98中,既可表示整数值,也可表示空指针,但可能产生混淆。
  • NULL:通过宏定义来表示空指针,虽然提高了可读性,但依然可能与整型 0 混淆。
  • nullptr:C++11引入,明确表示空指针,解决了 0NULL 的问题,推荐使用。

在现代C++中,优先使用 nullptr 来表示空指针,确保代码更安全和清晰。

共勉


http://www.kler.cn/a/527419.html

相关文章:

  • AJAX案例——图片上传个人信息操作
  • springboot 2.7.6 security mysql redis jwt配置例子
  • 【C语言】动态内存管理
  • 14-8C++STL的queue容器
  • 尚硅谷spring框架视频教程——学习笔记一(IOC、AOP)
  • 模型I/O功能之模型包装器
  • 26.Word:创新产品展示说明会【9】
  • Keepalived 安装
  • 基于微信小程序的实习记录系统设计与实现(LW+源码+讲解)
  • DeepSeek的崛起与OpenAI的守擂:AI大模型时代的竞争新格局
  • 自动化数据备份与恢复:让数据安全无忧
  • 动态规划 (环形)
  • Spring的AOP的JoinPoint和ProceedingJoinPoint
  • 网络编程复习
  • 从0开始,来看看怎么去linux排查Java程序故障
  • Day31-【AI思考】-深度学习方法论全解析——科学提升学习效率的终极指南
  • Synology 群辉NAS安装(7)lsof指令和synogear
  • 半导体SAP管理系统:数字化转型的驱动力
  • ComfyUI使用教程、开发指导、资源下载
  • 微服务配置中心 Apollo解析——Portal 关联 Namespace
  • 什么是麦克斯韦方程
  • 2025年01月31日Github流行趋势
  • 3 Spark SQL
  • 【leetcode】T541 (两点反思)
  • 新一代搜索引擎,是 ES 的15倍?
  • ARM嵌入式学习--第十一天(中断处理 , ADC)