空指针不指向任何对象,在C++11之后有如下几种生成空指针的方式
int *p1 = nullptr;
int *p2 = 0;
int *p3 = NULL; // 需要首先#include <cstdlib>
在C/C++11以前常用NULL来表示空指针,但两者含义并不相同。
在msvc中对NULL的定义如下
// msvc编译器
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
在C++编译器中NULL被定义为常量0,在C编译器中则将0强转为void*
为什么在C++和C中两者不同,因为C++中重载函数是根据参数进行匹配的,如果进行了void*的隐式转换则会带来重载函数的选择问题。
NULL为预处理变量,在cstdlib中定义,其值为0。预处理变量在编译之前由预处理器执行替换,预处理变量不属于命名空间std。
当用到一个预处理变量时,预处理器会将其自动替换为实际值,因此用NULL初始化指针和用0初始化指针是一样的。
ps:把int变量直接赋给指针是错误的操作,即使int变量的值恰好等于0也不行。
int *pi;
int zero = 0;
pi = zero; // 错误:不能把int变量直接赋给指针
在C++11之后引入了nullptr专门用来表示空指针,nullptr的类型为std::nullptr_t,而NULL则只表示0。
nullptr是C++11之后引入的字面值(纯右值,prvalue),用于表示空指针。nullptr是一种特殊类型的字面值,它可以被转换成任意其他的指针类型,但不能转换为任何其他类型。
// msvc编译器
void func(int) {
cout << "func(int)" << endl;
}
void func(void*) {
cout << "func(void*)" << endl;
}
int main()
{
int* pi = NULL;
int* pi2 = nullptr;
char* pc = NULL;
char* pc2 = nullptr;
func(NULL); // func(int) 如果在mingw中,会直接报错,显示该函数的调用有二义性
func(nullptr); // func(void*)
func(pi); // func(void*)
func(pi2); // func(void*)
func(pc); // func(void*)
func(pc2); // func(void*)
return 0;
}
ps:
nullptr不能用于算数表达式(+ - * /)
nullptr可以用于关系表达式 (== > <)
nullptr不能解引用(*)