C语言深入理解指针二(15)


前言

  本节课开始上点有意思的内容了!


一、指针变量类型的意义

指针的解引用

对比下面2段代码,我们在调试时观察内存的变化
在这里插入图片描述
调试我们可以看到,代码1会将n的4个字节全部改为0,但是代码2只是将n的第一个字节改为0
在这里插入图片描述
在这里插入图片描述

结论:指针的类型确定了,对指针解引用的时候就会有多大的权限(即一次能够操作几个字节)
比如 char* 的指针就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节,所以,就算每个指针变量的大小都是4/8个字节,但是我们仍然要注意类型

存在即合理,C语言既然给变量也设置的类型,就一定有它的理由

指针±整数

先看一段代码,我们调试来观察地址的变化
在这里插入图片描述
代码运行结果如下:
在这里插入图片描述
我们可以看出,char类型的指针变量+1跳过1个字节,int类型的指针变量+1超过了4个字节,这就是指针变量的类型带来的变化
结论:指针的类型决定了指针向前或者向后走一步有多大(距离)

void*指针

在指针类型中有一种特殊的类型是 void* 类型的,可以理解为无具体类型的指针(或者叫做泛型指针),这种类型的指针可以用来接受任意类型地址,但是也有局限性, void* 类型的指针不能直接进行指针的±整数和解引用的运算(因为不知道具体可以操作的字节数)
来个例子:
在这里插入图片描述
上述代码中,将一个int类型的变量的地址赋值给一个char类型的指针变量,编译器给出了一个警告,是因为类型不兼容,而使用void类型就不会有这样的问题
那么 void* 类型的指针有什么用呢?
一般 void* 类型的指针是使用在函数参数的部分,用来接受不同类型数据的地址,这样的设计可以实现泛型编程的效果,使得一个函数来处理多种类型的数据,这点,我们后面会单独介绍,相信我,这会让你感慨真酷!

二、const修饰指针

const修饰变量

变量是可以修改的,如果把变量的地址交给一个指针变量,通过指针变量的也可以修改这个变量
但是如果我们希望一个变量加上一些限制,不能被修改,这该怎么做呢?答案是采用const修饰符
在这里插入图片描述
上述代码中,n是不能被修改的,其实n本质是变量,只不过被const修饰后,在语法上加上了限制,只要我们在代码中对n进行修改,就不符合语法规则,就报错,致使我们没法直接修改n
但是我们绕过n,使用n的地址,去修改n就能做到了,虽然这样做是在打破语法规则

const修饰指针的时候
const可以放在的左边
const可以放在
的右边
也就是说,const int* pa 和 int* const pa都是可以的
但是它们限制的不太一样,前者限制的是*pa,后者限制的是pa
如图:
在这里插入图片描述

哦对了,插一个小知识,这一定要搞清楚
1.p指向a,p里面存放的是a的地址
2.p是变量,有自己的地址
3.*p是p指向的空间

我们再回来研究这个const修饰
1.第一个const修饰 *p ,意思是不能通过 p 来修改 p 指向的空间的内容,但是 p 是不受限制的
2.第二个const修饰 p ,意思是 p 变量不能被修改了,没办法再指向其他变量了,但是 *p 不受限制,还是可以通过p来修改p所指向的对象的内容
3.当然还有 * 左右都限制,这时候 p 和 *p 都被限制了

三、指针运算

指针±整数

因为数组在内存中是连续存放的,只要知道第一个元素的地址,顺藤摸瓜就能找到后面的元素
在这里插入图片描述
在这里插入图片描述

指针-指针

在这里插入图片描述
结论:指针-指针的绝对值是指针和指针之间的元素个数,前提是两个指针指向同一块空间

指针比较大小

先插个小知识,arr数组名其实是数组首元素的地址,arr就等价于arr == &arr[0];
在这里插入图片描述

四、野指针

  概念:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

野指针成因

1.指针未初始化
在这里插入图片描述
2.指针越界访问
在这里插入图片描述
3.指针指向的空间释放
在这里插入图片描述
地址确实返回来了,可是从函数出来,a的内存空间就还给操作系统了,这时候你还找出这个空间,甚至还想访问它

如何规避野指针

1.指针记得要初始化,指向谁要清楚,如果一开始不知道要指向谁,就指向空指针NULL

NULL是C语言中定义的一个标识符常量,值是0,0也是地址,这个地址是无法使用的,读写该地址会报错

2.小心指针越界
要明白指针只能访问哪些空间,不能超出范围访问

3.指针变量不再使用的时候,及时置NULL,指针使用之前检查有效性
当指针变量指向一块区域的时候,我们可以通过指针访问该区域,后期不再使用这个指针访问空间的时候,我们可以把该指针置为NULL

把野指针想象成一条野狗,野狗放任不管是非常危险的,所以我们可以找一棵树把野狗栓起来,就相对安全了,>在使用前,我们就要判断一下是否为NULL
在这里插入图片描述

4.避免返回局部变量的地址


总结

  本章开始已经有点意思起来了,但是难的还在后面!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值