用最简单的文字告诉你C语言指针的底层逻辑

数据都在内存里,你要从内存里读写数据,咋办?

首先我们是不是需要知道数据从哪里读,所以我们是不是需要地址。

然后我们是不是得知道我们读的是什么,所以我们需要类型。

你可能又问了,我还是不明白为什么需要类型,你想啊,你去读内存,我们是读1个位呢,还是1字节呢,还是4字节呢,还是8字节呢?我们是不是得知道每次读的长度啊,诶,类型的第一个好处就来了,比如我们知道char一般就是1字节,int大多时是4字节,知道类型了就知道长度了

但知道光知道读的长度还是有问题啊,比如int和float一般都是4字节,但它们在内存里存储的方式完全不一样,所以类型的第二个用处是,它能告诉你数据的存储方式。

所以你看,指针无非就2个玩意,类型和地址,比如代码

int *p=0x66666666;

说明指针p的地址是0x66666666,指针的类型是int型。

如果我们用*p=123这种代码,表示往0x66666666的地址里写入一个int类型的123;

那你会问了,如果我就想玩点花活儿怎么办,比如

int *p=0x66666666;
*p='a';
*p=114.514;
float a=*p;
p=p+2;

那得说少年你很有想法,虽然代码很花活,但其实你按上面的规律总结一下,还是非常好理解,比如第2行’a’是1字节,我们往指针p所在地址里写入’a’也就是asc码对应的数字65,不好意思,因为p的类型是int是4字节,所以哪怕你1字节就够了,你也要转换成4字节的65,然后写到地址0x66666666里

第3行,114.514是一个浮点数,同样的道理,因为我p是int,所以不管怎么样你都要迁就我,114.514转换成int就变成整数的114了,转换完再写进去

第4行从指针p里读数据,因为p是int类型,所以读出来也是int,也就是上面已经写进去的114,但左边的a是浮点类型,所以我们再把114转换成浮点数再赋值给a

你看很简单是不是,唯一指针最坑新手玩家的是第5行,p+2是多少,是地址0x66666666+2=0x66666668么,诶,不对,指针的加法运算要按类型来加,因为p是int类型,这里的int类型是4字节,所以应该是0x66666666+2*4=0x66666666+8=0x6666666e

上面都是大家都认识的汉字,组合起来大家肯定也都看得懂,来,你就死死抓住“在哪里–地址”“是什么–类型”两个概念去理解,实在绕不过去,你就想想如果你自己要写内存,你会怎么办,你会发现你自己琢磨来琢磨去,结果也是琢磨出和指针差不多的东西

作者:DBinary
链接:https://www.zhihu.com/question/663246320/answer/104692440459
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

发表回复