指针讲解(醍醐灌顶)

目录

引入

现在开始进入正题。

指针基础,我是想写小标题的,但是因为这些联系的太紧密了,不好分开(这个一定要先把前面的理解了,再看后面,不然会看不懂)

休息一下,我们将一个简单的。野指针


引入

在讲解指针之前我们先体会一个案例。我们每一个人都想要一套房子,买不起的话可以租。而别人要找我们的时候是不是都会到我们租的房子里去找。虽然现在有电话,但是之前是不是这样。而我们的电脑如果创建了一个变量那是不是相当于一个人,不过是变量电脑会分配一个房子,而我们要自己买。而电脑分配的这个房子,就是变量的地址,我们想要这个变量的时候我们就可以去这个地址找他。而这个地址(也可以叫指针)就是放在内存。就比如你想找一个妹妹,你问她我们可不可以见一面啊,她给了一个地址,你就可以按这个地址去找她。

这样可以了解到指针的重要性了吗,因为有了指针的话,我们就可以找到这个变量,但是有人说:我为什么要找,我在编辑器里面这个变量不是可以直接使用吗。这么说也对,确实不用找也可以直接用,但是指针可以为我们提供一种特殊的使用方式。

而因为我们电脑的不同,因此指针的大小也是不同的,在32位的机器下,指针的大小是规定的4个字节在64位的机器下指针的大小是8个字节。就这两种情况,指针的大小不是4就是8。

现在开始进入正题。

指针基础,我是想写小标题的,但是因为这些联系的太紧密了,不好分开(这个一定要先把前面的理解了,再看后面,不然会看不懂)

首先我们新建一个变量a int a = 1;而我们要这个a的地址,我们就需要用一个叫取地址的符号(&),用这个符号我们就可以拿到a的地址,我们可以用printf打印出来看一看

我们就可以看到是这个样子,打印出来的这一串就是a的地址。因为我这个是64位的环境下。而一个字节是8个二进制,而4个二进制可以变为一个16进制。

我们就成功拿到这个地址了,而我们拿到这个地址了就要去用吧,(难道你拿到一个妹妹的地址就不去找他吗,给你玩明白了,拿她的地址,勾引她把她变舔狗吧,这样太不好了,不想要就给我)

所以我们有了地址就要去使用,而这时我们就要一个叫解引用(*)的符号。

但是我们有了地址你要想放哪里,放口袋,又怕掉了,噢,拍一个照,手机掉不了吧,你在想,哎呀我怕我以后找不到啊,那你就可以建一个文件夹,叫做《没有男朋友的女生》,假如你是一个高富帅,你身边就有各种各样的女生,比如腿长的女生,脸好看的,有钱的,又有人说:破防了,一个都没有。没事,没事你还有计算机呢,你看我们也有各种各样的变量有int,char的,我们也可以把他们放到一起去,先是什么类型的女生,在加*表示地址。总结就是 int*(int类型的女生),char*(char的女生)。而这个文件夹,我们叫做指针变量,我们要把地址全部放到这里面。

而我们就可以对指针变量进行解引用,就可以得到变量a了

一定有人说这样太麻烦了,我自己打印a不就行了吗,为什么有这样绕一个圈呢,你想你找了一个女生,是不是要离开了才会要地址,方便下次去找他。因此,他一定是有他存在的道理,只不过现在还用不到。

有小聪明就说:哎,你不是说指针的大小就是4或8个字节吗,那为什么要有这些那些的类型,我直接随便写,反正都是怎么大。

哎,这个不一样,首先,我们每一个人都是会变的,可能这段时间喜欢腿长的,过了段时间,就喜欢脸好看的了。(声明不是我)所以我们是变量就是这样(破案了,是变量,不是我们)而我们为什么会喜欢腿长的呢,不知道,但是计算机为什么要int类型的,我知道,因为每一个字节都有自己的地址,电脑怎么知道要向后多少个(人家是有正当理由的,可以换),所以,电脑就要int*,就向后访问4个字节。

当然,还有一些女生是国民女神要什么有什么,而计算机也有,那就是void*,什么都可以传,但是就是不能使用,这个很正常,就像,网络上的女神是不是就可以看,不能摸。

当然,指针还可以加减整数,就比如一栋宿舍,里面是不是有很多的房间,如,第一层有10间房间,而我们拿到了第一间房间的地址(001),我们是不是就可以再向前走一个房间(002)

而我们走多远是不是取决于这个房间有多大,如果这个房间是4个字节,我们就走4个字节,如果是40个字节我们就走40个字节。(重点,后面很有用,一定要理解)

休息一下,我们将一个简单的。野指针

什么是野指针呢,看名字就知道,野的嘛,不是我们的。那不是我们的是不是使用起来就不安全。我们来看一个经典的例子

我们先创建一个变量,再创建一个有10个元素,每个元素是int的数组。我们再来一个for循环,把每一个数组的元素变为0,我们是不是只要变13次就可以了,虽然的越界访问了,但是这个好像说的不是越界访问,这个是栈溢出是意思。为什么,我们循环13次,我们是有限制的啊,为什么会一直循环下去呢。

画的丑,见谅。

我们看这个图再进行判断,当我们循环到10的时候,是不是刚好到了arr的最后一个,我们再走三个的时候是不是刚好到了i,我们就把i变为0,这样我们的循环是不是判断<13,成立继续循环下去。从而一直循环下去,使得栈溢出。因为我们的电脑他默认的不一样,使用这个情况也是很难触发。比如我这个都没有触发,但是我还是要说,因为这个太经典了。使用我们还是要避免野指针的出现。那怎么避免呢,总不能说避免就避免吧

我们就来介绍一个叫做断言的函数(assert),这个函数使用的时候要包含头文件(assert.h)

而这个函数的用法非常简单,就是符合的继续执行,不符合就报错。我们就这样写

assert(p != NULL);

就行了。

我们来说一个案例

我们在传参数的时候,因为这个参数是压栈压上去的,因此在函数中改变,不能改变还没传的参数,因此我们就可以使用传址调用,这样main函数中是变量就会随着函数变化而变化了。

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值