C++杂记:NULL与0的区别、nullptr的来历

转自: https://www.cnblogs.com/malecrab/p/5569707.html

某些时候,我们需要将指针赋值为空指针,以防止野指针。

有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;。
也有人直接使用0值作为空指针常量,例如:int* p = 0;。

前者可能觉得:NULL作为空指针常量,名字很形象,可读性较强。
后者可能觉得:NULL并不是C/C++语言的关键字,而是一个在标准库头文件

问题一:NULL与常数0值有何区别?

要弄清楚这个问题,我们采用问与答的形式来描述。

问:NULL到底是什么?

答:NULL是一个宏。

问:它的值是多少?

答:C/C++标准规定:它的值是一个空指针常量(null pointer constant),由实现定义。#1,#2

问:什么样的值才能称之为空指针常量?

答:C语言中常数0和(void*)0都是空指针常量;C++中(暂且忽略C++11)常数0是,而(void*)0 不是。#3,#4

问:NULL宏是在哪里定义的?

答:通常是在C标准库的

问:一般编译器的
#if defined(__cplusplus)
# define NULL 0    // C++中使用0作为NULL的值
#else
# define NULL ((void *)0)    // C中使用((void *)0)作为NULL的值
#endif

问:为什么C中(void*)0是空指针常量,而C++中不是?

答:因为C语言中任何类型的指针都可以(隐式地)转换为void*型,反过来也行,而C++中void*型不能隐式地转换为别的类型指针(例如:int*p = (void*)0;使用C++编译器编译会报错)。#5,#6

问:既然C/C++标准中,常数0都可作为空指针常量,为什么不统一使用0?

答:个人觉得由于(void*)0更能体现指针的意义,而常数0更多的时候是用作整数。因此,C语言中NULL定义选择了(void*)0。(仅供参考)

问题二:C++11中为什么要引入nullptr?

考虑着这样一个函数重载的情形:

#include <stddef.h>
void foo(int) {}     // #1
void foo(char*) {}   // #2
int main() {
    foo(NULL); // 调用#1还是#2?
}

从字面上来讲,NULL是个空指针常量,我们可能会觉得:既然是个指针,那么应该调用#2。但事实上调用的却是#1,因为C++中NULL扩展为常数0,它是int型。

根本原因就是:常数0既是整数常量,也是空指针常量。

为了解决这种二义性,C++11标准引入了关键字nullptr,它作为一种空指针常量。#7例如

void foo(int) {}     // #1
void foo(char*) {}   // #2
int main() {
    foo(nullptr); // 它会毫无异议地调用#2
}

猜你喜欢

转载自blog.csdn.net/qq_19784349/article/details/81545992