桥豆麻袋?指针原来如此之妙!!!

                                                       指针篇(1)

目录 :

1. 何为指针

2. 内存和地址

3. 指针变量


首先让我们来深入了解一下这个指针 

1.  何为指针

         何为指针,指针是C语言中的重要概念,它是一个变量(可以被修改的就是变量),用来存储地址,而它存储的就是另一个变量的地址,我们可以通过指针来访问或直接修改另一个变量的值,指针的定义方法是在变量前面加上个 * 号 ,例如  int*p  

2. 内存和地址

        当我们初步知道了指针的作用后,如果想要继续深入了解指针,就必须知道“内存和地址之间的关系”。

2.1 内存

          首先,内存就相当于我们生活中的宿舍楼,比如说这个宿舍楼的房间很多,足足有一百多间,如果有朋友想要来找我玩(深入交流),怎么让他快速又高效的找到我所在的宿舍呢?很简单,就是给每个宿舍安排上一个编号,也就是门牌号,这样就可以快速且高效的找到我所在的宿舍。

          那么,在计算机上其实也差不多,计算机cpu(中央处理器)在处理数据时,是从内存中读取的,处理完后又放在内存里面,那这些内存是如何高效的管理的呢???其实就是把内存分为一个个的内存单元,每个内存单元为1个字节,1个字节八个bit位

                  这就相当于八个人的宿舍,一个bit位代表一个人,而每个内存单元都有编号(这个编号相当于宿舍的门牌号),用于去访问宿舍的任意一位学生,有了这个编号,CPU可以快速找到这个内存空间。在生活中我们把门牌号叫做地址,在计算机中我们把内存单元的编号也叫做地址。

                 在C语言中,给了地址一个新的名字叫 :“指针”

所以我们可以理解为  : 内存编号 == 地址 == 指针

(注 : 这里并不是说一个字节只有一个地址,而是每一个bit位都有自己的地址)

2.2  内存和地址之间的联系

          当CPU访问内存中的数据时,必须知道这个数据存在于什么位置,这里我们就可以用 “&” 取地址操作符,取出变量的地址,从而查看这块空间中的情况。

          得到的是这个地址,那么让我们来调试一下,看看a是不是在这个地址(0a = 10,所以a变量就储存在这块空间里)

        这里我们可以看到,a确实是在这个地址(调试这里的0x00B3F930,前面的0x指的是16进制),因为是int类型的,所以存放了四个字节(地址旁边的 0a 00 00 00  各代表一个字节)。

        这里就有人要疑惑了,不是说1个字节有8个bit位吗?怎么这里只有两个,剩下的6个bit位呢?别着急,这里我们就要涉及到一个知识点,不管是什么类型的变量在内存中都是以二进制补码的形式储存的(这里我们先不用管补码,后面会讲到),而我们在调试时是以十六进制的形式展示的,所以当我们把十六进制转换成二进制,得到的就是8个bit位

         这里有个小知识要补充: 每次创建变量时,都会重新向内存申请一块空间,所以a的每次地址是不相同的~

        那这里的a是一个int类型,int类型是 4 个字节,每个字节都有自己的地址,也就是说a变量中存有4个地址,那我们怎么知道取的是第几个地址呢?很简单,上图!

        创建一个变量时,变量会向内存申请一块空间,而内存会对那块空间进行编址(单位是字节),所以这块空间的地址肯定是连续的,当我们&时,得到的就是4个字节中地址最小的字节的地址,也就是0x006FFD70,当我们找到第一个字节的地址后,可以顺藤摸瓜的访问到另外三个字节的地址。

        当我们去访问时,可以通过这个取地址(&)去访问这块空间,那我们找到这块空间后怎么通过地址去修改变量中的值呢???比如说把a = 10 的值改成 20 ,怎么做呢,很简单,用指针变量去修改。

3. 指针变量

3.1 指针变量的初步认识

           指针变量是什么?指针变量也是一种变量,就是指通过地址去修改变量的值,指针变量的定义方法就是int*p(这里的p可以改成自己想改的名字)

那怎么去使用这个指针变量呢???上一段简单的代码来解释:

        这里我们创建了个变量a = 10 ,我想把a的值进行修改,所以创建了个int*p(指针变量),把a的地址给了指针变量,用指针去访问并修改 a 的地址,看看打印结果:

        输出的是 20,这就是指针变量的作用。

        这里有人可能会问,a既然是变量,那给a再赋值上20不就好了,还要创个指针变量,这不是脱裤子放屁,多此一举吗???这里我们换个角度思考,a总有不方便的时候吧,当我们把a的地址给了p之后,代码的灵活性就会大大提高,后期就会慢慢理解了。

3.2  如何拆解指针变量
         上面我们介绍到了指针类型的运用方法、那怎么去理解拆开理解指针变量呢?

指针变量 : int * p
      这里我们看到p左边的类型是 int * 、指针变量中的*表示这个变量p是指针类型、前面的int则表示p指向的对象、是int类型的,这里我们引用上面的代码来解释一下:

           如果想要存放一个char类型的地址,应该存放在哪一个类型的指针变量呢?

答案是 : char*p,以此类推.......

3.2  解引用操作符(*)

           指针类型的拆解理解了之后,让我们顺着上面的代码往下看

            这里我们看到,当我们把a的地址交给 p后,就可以通过p去修改a变量的内容,那怎么去理解 * p 呢?这里就涉及到了一个操作符 ,叫做解引用操作符(*)

            前面我们讲到,p 里面存放的是a的地址,而不是a变量的值,所以要怎么才能获得a变量的值呢???聪明,就是解引用,p里存放着a的地址,当 * 对p 解引用时,就是对a进行更深入的了解,深入到里面存放了什么的地步(这么讲应该能理解吧),所以得到的就是a变量的值

            那*p就是把a解引用之后对a的值进行修改,所以输出结果为 20;

             看到这里,可能有人会有一些想法,比如说,当我把a的地址存进p里面后,我把 *p = 20 换成  p = 0 ,把a改成0 ,这时候a里面的值有没有被改变呢?

             答案是 并没有,因为p = 0只是改变了地址,当没有对指针变量p进行解引用,就没有办法得到a的值,并对其修改,那a的地址有没有被改成0 呢?

             答案还是没有,原因很简单,p里面装的确实是a的地址,那为什么这里a的地址没有改变呢?还是一样的原因,当你没有对p进行解引用,就得不到a的地址,也得不到a的值。那这里p=0,改变的是什么?其实是改变了p本身的地址

               同时也是给p赋了一个值

               因此可以得出,指针变量也有地址,不是说指针变量是存放地址的,所以它本身没有地址,我们可以打印看看p到底有没有地址

  总结 : 1. 当我们没有对p解引用时,就没有办法访问a的地址和它里面的值,更没有办法去修改

               2. 指针变量也是有地址的

               3. 当我们没有解引用时,p = 0 改变的就是它自身的地址,也是给自己赋值为零

                好的,到这里指针篇(1)也就到此结束了,下一篇再见!!!

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值