C/C++语言中的NULL

NULL不是C语言关键字,本质上是一个宏定义。C++的编译环境中,编译器预先定义了一个宏_cplusplus,程序中可以用条件编译来判断当前的编译环境是C++的还是C的。

NULL的标准定义
#ifdef _cplusplus // 条件编译
#define NULL 0
#else
#define NULL (void *)0 // 这里对应C语言的情况,NULL是一个表达式,是强制类型转换为void *类型的0,本质是0
#endif

NULL的本质:NULL的本质是0,但是这个0不是当一个数字解析,而是当一个内存地址来解析的,这个0其实是0x00000000,代表内存的0地址。(void *)0这个整体表达式表示一个指针,这个指针变量本身占4字节,地址在哪里取决于指针变量本身,但是这个指针变量的值是0,也就是说这个指针变量指向0地址(实际是0地址开始的一段内存)。

从指针角度理解NULL的本质
(1)int *p; // p是一个函数内的局部变量,则p的值是随机的,也就是说p是一个野指针。
(2)int *p = NULL; // p是一个局部变量,分配在栈上的地址是由编译器决定的,我们不必关心,但是p的值是(void *)0,实际就是0,意思是指针p指向内存的0地址处。这时候p就不是野指针了。
(3)为什么要让一个野指针指向内存地址0处?主要是因为在大部分的CPU中,内存的0地址处都不是可以随便访问的(一般都是操作系统严密管控区域,应用程序不能随便访问)。

为什么需要NULL
(1)第一个作用就是让野指针指向0地址处安全。
(2)第二个作用就是一个特殊标记。按照标准的指针使用步骤是:
int *p = NULL; // 定义p时立即初始化为NULL
p = xx;
if (NULL != p)
{
*p // 在确认p不等于NULL的情况下才去解引用p
}
p = NULL // 用完之后p再次等于NULL

注意:一般比较一个指针和NULL是否相等不写成if (p == NULL),而写成if (NULL == p)。原因是第一种写法中如果不小心把写成了=,则编译器不会报错,但是程序的意思完全不一样了;而第二种写法如果不小心把写成了=则编译器会发现并报错。

猜你喜欢

转载自blog.csdn.net/weixin_42325069/article/details/84147181
今日推荐