C语言指针 3

const对指针的修饰

上一篇我们讲到了指针的加减法,正因为指针也是一个值也可以进行加减法,我们平常的数值可以加const常量限定符修饰一个数如:const int a=50;这句就是将a设定为一个常量,在计算机中常量是不可修改的,这个a设定好后我们便不可通过a去修改这个地址内值,因为会有语法的限制,编译器会把a认定为一个常量,如图。

虽然被语法限制了对a的修改,但是我们知道这个空间内存的就是一个变量并不是被定义的常量。

如上图,虽然a是被限定了,但是当我们拿到a的地址直接对这个空间内的值进行修改时可行的。那么我们对a的常量限定是否就没有意义了呢,并不一定因为对指针我们也是可以加常量限定符的。

上图中我们给指向a的指针也加上了常量限定符后便无法使用指针p来对这个地址的值进行修改。但是请注意同上const int a一样,这个const修饰的是p这个指针,a内空间的值还是一个变量这一点时不会变的,若我们继续定义一个指针赋予a的地址这个值一样是可变的。

我们知道指针本身也是一个值是可以变的,若我们希望这个指针值不变就固定指向这个区域的话我们可以如下图去定义:

这就是对p的直接修饰,这时的p的值便不会再被修改。

在上图中我们又尝试了将const放在int和*之间这时的效果是无法通过p指针去修改这个地址内的值。由此我们可以看到编译器对指针的看待方式,p就是一个变量值,当变量与*结合在一起的时候才会将其看待为一个指针,所以这个const只会区分是p变量还是p指针。

野指针

若我们将内存想象成是一个集有很多小房间(1byte)的一个大房子,里面每一个小房间储存我们放进去的数据,那么地址就是每个小房间的门卡,当我们有了门卡后就能肆无忌惮的进入每一个房间访问所有的值了,但是有些值呢是不能被随意修改的。想想我们在大房子里有一间小房子里面是装的供水装置,若是我们随意进入这个房间并修改了装置结果可能是整栋房子都无法供水了。

野指针就是我们并不知道我们拿到的这个地址究竟是指向哪里的,有可能是指向空的空间,对其访问或者修改后并不会有什么影响,也有可能是指向我们某一个程序后面需要使用的数据,修改了会导致后续程序的崩溃,更甚的可能会指向系统正在使用的空间,一旦修改便会直接崩溃。

野指针的成因

一般我们使用指针都是会有明确的方向需要这个指针指向某一块空间的,那么我们为什么还会出现野指针。

我们在创建指针变量时可能的确是有明确使用思路的,但是若当时需要指向的空间还没有创建出来我们便无法对其进行有用的赋值,这时没有被赋值的指针便是野指针这个指针默认值为随机值,指向是随机的、不正确的、没有明确限制的,而我们正确做法应该是在无法对指针赋值时先将指针赋为‘NULL’,空值在计算机中就是‘0’,而0这个地址是被规定了无法使用的,当我们修改这个空间的值时便会报错。

指针越界

我们知道指针时可以进行加减法计算的

如图,因为数组是一个连续的空间,当我们使用指针进行加减法操作可以访问到数组中后面的数据的。但是数组的数据是有限的,这里我们数组只有5个数据,但是指针的加减法并没有限制,特别在循环的语句中当我们通过指针去访问数组元素,一旦超过数组的数据个数便会造成越界,出了这个数据的空间范围后面的空间是用来做什么的我们并不清楚这时便形成了野指针越界访问了。

指针指向的空间已被释放

当我们使用动态开辟内存空间时,在使用完后自然需要将空间释放掉,不然这个空间会存在堆区中的直到程序结束都会一直存在很容易造成空间浪费。

我们对空间释放过后这个空间就会交会给系统由系统进行再分配,而我们在动态开辟内存时一般都是由指针来管理这个空间的,释放过后指针任然指向这个地址但是这个空间的用途已经截然不同了,这时也会造成野指针的,所以我们最好释放空间的同时将指针置为NULL。

返回局部空间创建的地址

当我们调用函数时会传参,当我需要这个函数的返回值时也需要接收它的返回值,但是这个返回值若是指针的话就有可能出现野指针的情况,我们在函数中定义了一些变量,返回的指针指向这些变量,那么当我们返回时这个函数的栈空间已经被释放,返回的指针还是指向这个空间那我们接收的就是一个野指针而已。我们需要注意不要返回一个指向栈空间地址的指针。

assert断言

assert.h头文件中定义了一个宏‘assert()’

图中我们使用assert进行了一个断言,即assert()括号中的表达式不会真便会直接报错并表示所在的行号可以方便我们排查问题。

当我们不需要这个断言的时候取消也不需要去一行行找就在定义头文件的上面定义一个宏‘NDEBUG’即可禁用,一般都会在Debug环境下使用,release环境下禁用。

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值