C进阶指针(3)----NULL指针

过了几天,小明又找到博主,问之前计算器程序中的NULL指针是什么,虽然杰哥讲过,但没怎么听懂。

既然这样,我们就只好为小明再开一篇文章,探究以下NULL指针。

什么NULL指针?

以下选自某度某科

 C语言的NULL指针是什么?

其实C语言的NULL指针和某度某科所说的,是大同小异的,区别很小的,NULL就是一个指向了空值,但是注意,NULL不是直接定义成了一个常量0,而是(void *)0,这是因为任何类型的指针变量赋值NULL时都能够赋值0,我们来看一下定义就明白了

NULL的定义(VS2022)

 #define NULL ((void *)0)

这样定义的好处是假设我有一个字符型指针ch,我们需要让他指向内存地址为0的地址时,就可以为他赋值NULL指针,在假设,我们定义一个整形指针变量p,我们也需要让他指向内存地址为0的地址,那么如果NULL单纯是常量0的话,就不能完美让字符型指针ch接收,依次类推,所以,为了兼容所有类型的变量,这里就引入了万能指针的概念,即(void *)指针。

这时候小明就又有疑问了,什么是万能指针(void *)?

那么有关这部分内容我也会出单独一篇文章来阐述,这里篇幅有限,不过多解释。

虽然小明没得到答案,但还是认为吧NULL指针给搞明白比较好,于是问博主能不能以代码案例来讲解

当然可以,案例1

我们有以下代码

#define _crt_secure_no_warnings 1
#include<stdio.h>
void test()
{
	printf("Hello world!\n");


}
int main()
{
	char a = 'a';
	char* ch;
	ch = &a;
	ch = NULL;
	printf("%c\n", ch);

}

这段代码平平无奇,但却能很好的说明,为什么NULL要定义为(void *)

首先,我们打开VS2022,写下以上代码,按“F10”进入VS2022的调试模式,按,F10一直到如图所示       

 让左侧小箭头指向ch = NULL;这行代码,因为,此时我们检查以下此时ch指向a时的地址是多少。

然后,我们找到VS2022菜单栏中的“调试->窗口->内存->内存1”,如图所示

 即可查看每个变量的实时地址,以上操作无误,应是下图所示

然后,我们在“地址”搜索栏中输入“ch”,按回车键,得道此时ch的地址,如下图所示

 

我们可以发现,此时的ch的指向0x000000B24A0FF620,即a变量的地址。

记录数据,以方便我们一会与NULL指针作比较

接下里,我们继续按“F10”,一直到如图所示

 

 注意:不要按过头了,导致调试结束,从而退出程序,这时候就无法使用内存功能,因为只有在调试模式下才能使用内存模式

重复找内存功能的操作,打开内存1

 这次,继续在“地址”搜索栏中输入“ch”,按回车键,得到此时的NULL指针,如图所示

 

此时,我们居然发现,ch指向0地址,即常量0的地址,若ch为int类型,最终结果也是如此,所以,这也是为什么吧NULL定义为(void *)。

这时候,问题超多的小明又问了一个问题

那NULL指针可以解引用吗?

不可以!!!

因为NULL指针的地址时0x0000000000000000,这也是操作系统的存放0的地址,为了保护系统,所以,NULL指针只可以被指向,而不可以解引用!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值