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

nullptr vs NULL:C/C++ 空指针的演变史

nullptr vs NULL:C/C++ 空指针的演变史

📚 目录

  1. 基本概念
  2. 历史演变
  3. 技术差异
  4. 实际问题
  5. 最佳实践
  6. 项目建议

🎯 基本概念

NULL(C语言传统方式)

// NULL 的常见定义(在 stddef.h 中)
#define NULL ((void*)0)     // C语言风格
#define NULL 0              // C++常见定义

特点

  • 📜 来自C语言时代
  • 🔢 本质是一个宏定义
  • ⚠️ 实际值是 0(void*)0

nullptr(C++11 现代方式)

// nullptr 是C++11引入的关键字
// 不是宏,是语言内置的空指针常量
int* p = nullptr;  // ✅ 类型安全的空指针

特点

  • ⚡ C++11引入的关键字
  • 🎯 专门用于表示空指针
  • ✅ 有自己的类型:std::nullptr_t

📖 历史演变

1️⃣ C语言时代(1970s-1990s)

// 只有 NULL
int* ptr = NULL;
if (ptr == NULL) {// ...
}

2️⃣ 早期C++时代(1990s-2011)

// 继承C的NULL,但有问题
void func(int);
void func(char*);func(NULL);  // ❌ 歧义!调用哪个?

3️⃣ 现代C++时代(2011-至今)

// C++11引入nullptr解决问题
void func(int);
void func(char*);func(nullptr);  // ✅ 明确调用 func(char*)

🔬 技术差异

差异1:类型安全

// NULL 的问题
void process(int value) {printf("处理整数: %d\n", value);
}void process(char* ptr) {printf("处理指针: %p\n", ptr);
}// ❌ NULL 是 0,可能匹配到 int 版本!
process(NULL);      // 可能调用 process(int),编译器警告// ✅ nullptr 明确是指针类型
process(nullptr);   // 一定调用 process(char*)

差异2:类型推导

// NULL 的问题
auto p1 = NULL;      // ❌ p1 的类型是 int,不是指针!
auto p2 = nullptr;   // ✅ p2 的类型是 std::nullptr_t// 模板中的问题
template<typename T>
void func(T* ptr) {// ...
}func(NULL);          // ❌ 可能报错:无法将 int 转换为 T*
func(nullptr);       // ✅ 正确推导

差异3:隐式转换

// NULL 可以转换为整数
int value = NULL;    // ✅ 编译通过,value = 0
bool flag = NULL;    // ✅ 编译通过,flag = false// nullptr 不能转换为整数
int value = nullptr; // ❌ 编译错误!
bool flag = nullptr; // ❌ 编译错误!// 但可以转换为 bool
if (nullptr) {       // ✅ 编译通过,结果为 false// 不会执行
}

差异4:重载解析

void test(int n) {printf("整数版本: %d\n", n);
}void test(void* ptr) {printf("指针版本: %p\n", ptr);
}// NULL 的问题
test(NULL);          // ❌ 二义性!可能调用 test(int)
test(0);             // ✅ 调用 test(int)
test((void*)0);      // ✅ 调用 test(void*)// nullptr 明确
test(nullptr);       // ✅ 一定调用 test(void*)

🐛 实际问题案例

案例1:函数重载的陷阱

class SmartPointer {
public:SmartPointer(int* p) {printf("构造:整数指针\n");}SmartPointer(char* p) {printf("构造:字符指针\n");}
};// 使用 NULL
SmartPointer sp1(NULL);      // ❌ 编译错误:二义性!// 使用 nullptr
SmartPointer sp2(nullptr);   // ❌ 仍然有二义性(两个都是指针)// 但至少不会匹配到 int 类型

案例2:模板元编程

template<typename T>
void process(T value) {if (value == nullptr) {  // 只对指针类型有效printf("空指针\n");}
}process(NULL);       // ❌ NULL是int,无法与nullptr比较
process(nullptr);    // ✅ 正确

案例3:您项目中的实际代码

// MessageWindow.cpp 第438-442行
MessageWindow::~MessageWindow()
{    if (bgAreaA.pu8PlatteMem)          // ✅ 检查非空{vPortFree(bgAreaA.pu8PlatteMem);bgAreaA.pu8PlatteMem = nullptr;  // ✅ 使用nullptr}
}// 如果用 NULL
if (bgAreaA.pu8PlatteMem)
{vPortFree(bgAreaA.pu8PlatteMem);bgAreaA.pu8PlatteMem = NULL;      // ⚠️ 也能工作,但不如nullptr明确
}

📊 对比表

特性NULLnullptr
引入时间C语言(1970s)C++11(2011)
本质宏定义 #define NULL 0关键字
类型intvoid*std::nullptr_t
类型安全❌ 不安全✅ 安全
函数重载❌ 可能二义性✅ 明确匹配指针
模板推导❌ 推导为int✅ 推导为指针
转换为int✅ 可以❌ 不可以
转换为bool✅ 可以✅ 可以
C兼容性✅ C和C++都能用❌ 只能C++用
推荐使用C项目C++项目 ✅

⚡ 最佳实践

C++项目(推荐 nullptr

// ✅ 现代C++风格
int* ptr = nullptr;
if (ptr == nullptr) {// ...
}void* mem = pvPortMalloc(100);
if (mem == nullptr) {return -1;
}delete ptr;
ptr = nullptr;  // 防止悬空指针

C项目或C/C++混合项目(使用 NULL

// ✅ C语言风格
int* ptr = NULL;
if (ptr == NULL) {// ...
}void* mem = malloc(100);
if (mem == NULL) {return -1;
}free(ptr);
ptr = NULL;

您的项目(混合使用)

// 您的项目中两者都在用
bgAreaA.pu8PlatteMem = nullptr;  // C++风格
if (NULL == pu8Payload) {        // C风格return FALSE;
}

建议

  • 新代码:统一使用 nullptr
  • 旧代码:保持 NULL 不变(避免大规模修改)
  • 混合使用:可以接受,但同一文件内尽量统一

🎯 您的项目建议

当前状态

// ParcelDispatcher.cpp - 使用 NULL
if (NULL == pu8Payload || NULL == pu8Resp) {return FALSE;
}// MessageWindow.cpp - 使用 nullptr
bgAreaA.pu8PlatteMem = nullptr;
if (bgAreaA.pu8PlatteMem) {vPortFree(bgAreaA.pu8PlatteMem);
}

建议策略

  1. 协议层(C风格为主):使用 NULL

    // ParcelDispatcher.cpp
    if (NULL == pu8Payload) {return FALSE;
    }
    
  2. UI层(C++类为主):使用 nullptr

    // MessageWindow.cpp, AlarmWindow.cpp
    if (m_pTextBox == nullptr) {return -1;
    }
    m_pTextBox = nullptr;
    
  3. 混合代码:优先使用 nullptr(更安全)


📝 总结

场景推荐理由
纯C项目NULLC语言不支持nullptr
纯C++项目nullptr类型安全、现代标准
C/C++混合项目看情况协议层用NULL,UI层用nullptr
您的项目两者都可以已经混合使用,保持风格统一即可

核心原则

  • 一致性 > 完美性(同一文件内保持统一)
  • 可读性 > 教条性(团队习惯最重要)
  • 安全性:新代码优先用 nullptr
http://www.dtcms.com/a/487162.html

相关文章:

  • 深圳企业网站制作公司介绍网站防盗链设置
  • 搜索别人的网站是带logo的请问怎么做的精准广告投放
  • latex中自定义公式编号
  • 苏州正规做网站公司网站建设初期的需求分析
  • codetop高频(1)
  • LeetCode 994. 腐烂的橘子
  • 网站设计师需要什么知识与技能咸宁网站建设哪家专业
  • Python爬取百度地图-前端直接获取
  • thumos14数据集学习
  • 持续集成/持续部署(CI/CD)
  • HTTPS 的加密过程~
  • 用服务器ip做网站不配置iis做网站
  • 成都企业网站建设哪家好做网站模板链接放哪里
  • 网站手机端做app开发工具网站开发图标
  • 华为OD-21届考研-Java面经
  • PyTorch 实现多种 CNN 模型并采用集成方法提升 CIFAR-10 分类性能
  • 网站建设常用软件宣传链接用什么软件
  • 合肥响应式网站开发方案wordpress 本地 搭建网站
  • 国内做游戏破解的网站专门做2手手机的网站
  • 深度学习进阶(二)——视觉与语言的融合:多模态模型的架构演化
  • html做的旅游网站wordpress按作者分类
  • Jmeter 线程组、定时器、监听器、后置处理器常用配置说明
  • Jmeter分布式集群搭建与使用
  • 【Pytorch】MLP反向传播
  • 【pytorch学习打卡挑战】day2 Pytorch张量运算API
  • 【GESP】C++三级练习 luogu-P1597 语句解析-系列题目1
  • 宏杰zkeys网站模板浙江省工程建设监理管理协会网站
  • kotlin中MutableStateFlow和MutableSharedFlow的区别是什么?
  • 工作室主题网站网站备案被注销的原因
  • 网站改版建议常州城乡建设学校网站