【const修饰指针】【指针运算】【野指针】深入了解指针(1)

一.const修饰指针

大家知道,变量是可以修改的,如果我们把变量的地址交给一个指针变量,我们通过指针变量也是可以修改这个值。那如果我们不希望这个变量被修改,我们应该怎么做,把这个值给固定住呢?const就起到了这样的一个作用。关于用const修饰,我们只需要记住,const就像是一把锁,把能修改的东西给上了锁。

我写一个用const修饰的代码。

这里如果调试的话就出现了错误。

注意:这里的a变量用了const修饰,a就有了常属性(也就是不能被修改了)但a不是常量!

但是!虽然a变量不能改了,但我就是犟,我就是要改它,那我们可以用指针变量了。

也许你会有疑问,有了const的a还能被修改?这就相当于有一个房子,我们把a门给锁上了,那我们可以从p门偷摸的进去。但我们本来就不希望a被改,我们用指针变量p破坏了这个规则,那么我们该怎么样做,不让指针变量去改变这个值?

直接用const来修饰指针不就行了。

1.放在*前面的const

这里我把cosnt放到了*前面,这个时候我们再把*p赋予一个新的值,这时编译器就会报警告。大家可以这样理解:我们把const放在*前面,cosnt修饰的就是*p,就相当于我们把*p上了锁,后面的*p=0当然是不行的。这里我们想通过指针变量再去修改a的值就不可取了。

2.放在*后面的const

我们把const放在*前面和*后面是完全不一样的。

这里我们把const放在了*的后面,我们发现*p是可以被修改的,但是我们给予指针变量p一个新的地址,这里就出现了红色波浪线(就是编译器报了警告,这个代码是错误的)。这里const的作用就是给p所指向的地址上了锁,这里指向的是a的地址,那么p就只能指向a的地址,无法被修改。

跟把const放在*前面的时候理解方式一样,这里const把p上了锁,p在想改变指向的地址是不行的。

二.指针的运算

1.指针与整数的运算(+-)

这里指针与整数的运算挺简单的,比如一个int* p = &a,这里我给p加上1,p+1也就是跳过的4个字节,更加准确的说跳过的是1*sizeof(int)个字节,它跳过的就是一个整型的指针。当然咱们可以写一个公式:type*p,p+n,跳过的就是n*sizeof(type)个字节。

我们可以用数组来简单写一下。

这里我们把a数组的首地址给了p,p在后面依次递增,每一次递增的就是一个int类型的长度。

2.指针与指针的运算

关于指针与指针之间的运算,大家可以先想一下日期与日期之间的运算,这两者其实是大差不差的。我们可以先想一下,假如我们把两个日期相加,那加出来的是个什么东西?答案是:那什么东西也不是。我们再想一下,两个日期相减得到的结果是什么?答案是:两个日期之间的天数。那么指针减指针也就显而易见了,得到的肯定是个整数,而这个整数就是两个指针之间的元素个数,我们依然用数组来测试一下这个结论。

这里我们取出两个元素的地址之后 把它们相减,得到的就是两个地址(指针)之间的元素个数的差值。               但一定要注意,两个指针一定一定要指向同一块空间!

如果有两个不同的数组,把它们分别取出一个地址相减,这种做法是肯定不行的。是错误的!

3.指针的关系运算

说白了,就是比较大小。大家知道地址也是有大有小的。话不多说,直接上代码。

由于地址都是连续的,我们在定义数组的时候就已经决定了地址从哪里开始的,一直递增直到结束。

三.野指针

1.野指针概念即野指针成因

概念:野指针就是指向的位置是不可知的,是随机的,不正确的,没有明确限制的。野指针形象的说,就是一条没有主人的野狗(在大街上乱窜的那种)。有一些情况可能会导致野指针的出现。

成因:(1)指针没有初始化(2)指针越界访问(3)指针指向的空间释放。我来写三个代码来分别说一下。

第一种:首先是指针没有初始化,这个很简单。

指针必须要有明确的指向,这里的p是一个局部变量,大家记住,如果局部变量不初始化,存的是随机值。这里的p就是个野指针。

第二种:指针越界访问 

这个代码就是一个指针越界访问的一个实例,咱们声明的这个数组a,最多就只有a[9],而这里直接到了a[10],访问到了第11个元素,肯定是不行的啊。这里就是指针访问越界导致的一个野指针。

第三种:指针指向的空间释放

大家可以先看一下这个代码正不正确。

在我们编译器运行的时候,首先进入主函数,执行主函数的第一行代码调用test()函数,然后在内存里申请的一块空间,在test函数内创建了变量a,返回a的地址。一直到这里,大家有发现什么不对吗?咱们是在test函数内创建的变量a,等到出了test函数,这个变量就自动销毁了,咱们再把return出的值给p,p指向了一块销毁的空间,这是可取的吗?答案也是肯定的,肯定不行,这也是货真价实的野指针。

2.如何规避野指针

如果我们的代码中有野指针,就相当于在我们的代码中出现了一条乱窜的疯狗,那我们该怎么样规避这条疯狗的出现呢?最重要的就是初始化了。

第一种:初始化:(1):如果我们知道指针该指向哪里,就给指针明确的地址

              (2):如果不知道该指向哪里,就给指针初始化一个NULL(NULL在c中定义的是一个标识符常量,值是0,0也是地址,但这个地址无法使用,如果使用的话会报错)。这个过程,就相当于把疯狗拿绳子栓了起来。

第二种:小心指针越界,在使用的时候,你申请了多大的空间就使用多大的空间。

第三种:如果指针不再使用了,及时的把指针置为NULL,等以后再要使用的时候,检验它的有效性。(其实在使用指针时,最合适的使用方法就是要先判断指针是否合法,也就是要先判断指针是否是NULL,后面我会讲一下assert断言,也是用来判断的。)

第四种:要避免返回局部变量的地址,就是我刚刚在上面说的那个,指针指向的空间释放的问题。

感谢大家的观看,如果有错误,请大家多多指正

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值