在 c 和 c++ 中分别是这样定义的
#ifndefNULL#ifdef__cplusplus#defineNULL0#else#defineNULL((void*)0)#endif#endif知识铺垫
- C 语言里的 NULL 本质是 (void)0(void类型的空指针);
- C++ 里的 NULL 本质是整数 0(宏定义直接替换为 0);
- C 中的 void* 可隐式转换为其他指针类型(如int*),也可通过强制转换转为 int 型;C++ 中void* 不能隐式转为其他指针类型,但可通过reinterpret_cast/C 风格强制转换转为int型(非推荐);
- C 和 C++ 中的 void* 都可以显式类型转换为其他指针类型;
- nullptr 可以隐式类型转换为任意指针类型,也可通过reinterpret_cast强制转换为 int 型(但不推荐,且违背nullptr的设计初衷)。
voidf1(intx){printf("f(int x)");}voidf2(int*ptr){printf("f(int* ptr)");}在 C 语言中,NULL是(void*)0,可隐式转换为int类型,因此直接调用f(NULL)会匹配f2函数;若想调用f1函数,则需要将NULL强制类型转换为int型(如f((int)NULL))
在 C++ 中,NULL等价于整数0,直接调用f(NULL)时编译器会优先匹配接收int参数的f1函数;若想调用f2,需手动将NULL显式转换为int(如f((int*)NULL)),而非“无法调用 f2”。
这就会导致一个典型问题:在 C++ 中你本意想用空指针 NULL 调用处理指针的f2函数,却因它等价于整数 0,而错误调用了f1函数。因此 C++11 引入了非常重要的关键字 nullptr——它是专门用于表示空指针的常量,类型为std::nullptr_t,不会被隐式转换为整数类型。用nullptr调用上述函数时,会精准匹配f2,彻底避免这类调用错误。