NULL和nullptr的区别

思维导图

NULL和nullptr的区别_第1张图片

1.C++98的指针空值

一般我们在声明一个变量时,最好给变量一个合适的初始化值,否则可能会出现不可预测的错误。而我们一般是按照如下方法初始化的:

int main()
{
	int a = 0;
	int b = NULL;
	//...
}

NULL实际是一个宏,我们在C头文件(stddef.h)中,可以看到如下代码:

#ifndef NULL 
#ifdef __cplusplus 
#define NULL    0 //被定义为常量0
#else 
#define NULL    ((void *)0) //或者被定义为无类型指针(void*)
#endif #endif

从头文件我们可以看出,NULL被定义为了常量0或者被定义为了无类型指针(void*)。
但是因为NULL存在二义性,所以会出现如下的错误情况

void fun(int)
{
	cout << "f(int)" << endl;
}

void fun(int*)
{
	cout << "f(int*)" << endl;
}


int main()
{
	fun(0);
	fun(NULL);//本意是调用第二个函数
	fun((int*)NULL);

	system("pause");
	return 0;
}

NULL和nullptr的区别_第2张图片
程序本意是享用fun(NULL)调用指针版本的(int*)函数,但是由于NULL被定义为0,所以与程序的初衷不同

总结

在C++98中,常量0即可以是一个整形数字,又可以是无类型的指针(void*)常量,但是编译器默认情况下将其看作一个整型常量,如果像按照指针方式来使用,需要强行转换为(void*)。

2.nullptr

为了考虑兼容性,C++11并没有消除常量0的二义性,C++11给出了全新的nullptr作为空指针。
为什么C++11不对NULL做拓展呢?

  • 1.NULL之前本来就是一个宏。
  • 2.不同的编译器厂商可能对NULL实现不太相同,可能会影响旧的程序。

为了避免混杂,C++提供了nullptr:代表一个指针常量。

nullptr是有类型的,其类型为nullptr_t,仅仅可以被隐式类型转换为指针类型,nullptr在头文件被定义为:

typedef decltype(nullptr) nullptr_t;

注意:

1.在使用nullptr表示空指针时,不需要包头文件,因为在C++11中他是以关键字存在的。
2.在C++11时,sizeof(nullptr)和sizeof((void*)0)所占字节相同,都为4。
3.为了提高代码的健壮性,后续表示指针空值时最好使用nullptr。

你可能感兴趣的:(面试题总结)