C++中*p,&q,m以及**r,*&n,a[],*b[]的通俗易懂解释

30 篇文章 4 订阅

虽然已经码代码有些年头了,但是很多时候,还是容易混淆。今天痛定思痛,突发奇想,条分缕析,算是整明白七七八八了。

一、先整清楚一些关键的概念

  1. 数据在电脑中存储,都是0和1的二进制存储方式,它本身不带任何的数据类型属性。
  2. 那平时我们定义的数据类型,比如int,char,又如何解释呢?那就像是人为定义的一堆方盒子,每个盒子有多大(即多少位),每一位代表的含义(比如最高位是否为正负,比如double的多少位代表底数、指数、尾数之类的,都是人为规定的),然后就可以根据这一长串的0、1,得出这个盒子代表的是一个什么数。同样的一串0、1,放在不同的盒子里,解读出来的值是不一定相同的。
  3. 数据在电脑中存储,包括在内存中的临时存储,都不是乱放的,都是有位置的,我们称之为地址,就像一个个大小相同的快递柜,都有自己的编号,编号就是地址。
  4. 注意,标识快递柜的地址,同时也可能是放在快递柜中的货物,这个存放这地址的快递柜,也有自己的地址,这个地址,换言之,就是想要的数据的地址的地址。也就是说,如果你想要找到这个快递,你拿到的是一个地址的地址,你首先得根据这个地址,打开第一个柜子,获得下一个地址,然后打开第二个柜子,才能拿到东西。以此类推,如果比较淘气一点,你如果想下个连环套,那你可以再多套几环,地址的地址的地址。

二、*p,&q,m的区别和关联

1 区别

  1. 定义变量int *p。*p就是指针,注意,是 * 和p一起,是一个指针,如果只是单独的p,我的理解是,p就是你想要的数据的地址。也就是说,指针不直接指向数据,而是指向存放数据的地址,也就是说这里的p的值,是数据的地址的值。
  2. 定义变量int &q。等同与int q,加不加一个&并没有太大意义。这里&和p如果合在一起看,就是&p,这个时候,也代表了地址,是谁的地址呢,就是数据q的地址,也就是说,这里的&q指向的是数据的地址,而q是具体的数据,int q里的q,也是具体的数据,所以int q和int &q是一个意思。不要复杂化了。实际中,并不会直接定义一个int &q,使用,而是在函数的定义中传参使用,这个后面会细说。
  3. 定义变量int m,这个很明显,m就是数据了。

2 关联

int *p; //定义一个指针    
qDebug()<<p;
int m = 100;  //定义一个普通变量
int q = m;    //定义一个普通变量q,并赋值
p = &q;  //给指针p赋的值,一般是地址
qDebug()<<p;
qDebug()<<*p;
qDebug()<<&q;
qDebug()<<q;

输出的结果如下:

0x56091386e35d
0x7fff9e19aa18
100
0x7fff9e19aa18
100

由上面的结果可以看出来几点:

  1. p代表的确实是地址值,*p代表的地址位置的变量值。
  2. &q输出的值,是变量地址,而q是变量的值。
  3. 地址的值也是一样可以改变的。p的地址值和&q的地址值相同。指针p指向的位置发生了改变。
    总结一下:
  4. 变量值,地址,指针之间是有环环相套、步步为进的关系的。定义一个指针*p,指针指向的地址就是&q,q的值就是变量。这是一个依次展开的过程,当然如果不想要指针,可以直接定义中间一个环节。比如直接定义变量。

3 重点解释

归纳总结出4个解释如下,有点理不清的同志可以熟记:

  1. 前提条件:在计算机中,存在一个这样的关系。有一个具体的数值,有该数值存放的地址,该地址有一个指针指向它。举例说,有一个盒子,盒子里有货物,盒子上有个独一无二的编号,但同时为了方便称呼,这个孩子有一个别的叫法,比如老鱼的盒子。后面的解释,依托此进行层层剖析。
  2. 解释1: *p的解释, *p就是指向地址的指针,即“老鱼的盒子”这个称呼。同时, *p的值就是变量值,即盒子里的货物。
  3. 解释2: p的解释, p就是地址,即盒子这个独一无二的编号。
  4. 解释3: &q的解释, &q就是地址,即盒子这个独一无二的编号。所以&q和p之间可以互相赋值,变化的是地址。
  5. 解释4:q就是变量值,即盒子里的货物。所以q和*p之间可以互相赋值,变化的是变量值。

三、**r,*&n,a[],*b[]的区别

阅读完上述内容后,到了这一部分,理解起来就顺畅了。

1 **的理解

**r,可以拆开解释,先把 * r 当成一体当做p,那么 **r 就成了 * p,根据*p解释,那么p就是地址,最前面解释过,地址也是存储在内存中的值,只是他代表的含义是地址而已,那么再看 *r,r也是地址的值,那么就清楚了,这是套了两层的,地址的地址。

2 *&n的理解

这里,可以将&n理解成一个整体,那根据 *p 解释,&n就是这个p,就是地址值,那么n是什么呢?再来理解一下&n,根据 &q的理解,那么n就是这个q,即一个具体的变量值。所以,绕了半天你会发现,这个 *&n启示就是n。

3 a[]的理解

不要想复杂了,这个就是一个数组。a指向的是这个数组的首地址。

4 *a[]的理解

这个理解起来需要将*a合并理解,也就是将 a看成一个整体。根据上文的p解释,p 就是一个变量值,比如int b=*a,那么a[],就可以理解成b[],那就好理解了。

四、函数传参中的理解

函数传参主要有两种方式,一种是引用,一种是传值。

1 引用

void test1(int &q)
{
{

网上很多教程,都告诉你这p启示就是一个传入的参数的别名,操作的还是原数据,会改变原数据的值。但为什么会这样呢。启示很好理解,把&q当成一个整体,那么根据&q的解释,传入的就是变量存储的地址,所以名称什么的无所谓,管你是老鱼的盒子还是老张的盒子,更重要的盒子编号,即地址已经知道了,你就可以根据这个地址找到内存中的这个变量,然后修改他的值。

2 传值

void test2(int m)
{
{

传值的特点是,不会影响到原来的值,相当于重新复制了一份。这个也很好理解,因为你这个时候传入的参数,就是你盒子里的东西,他没有传入地址,相当于你从盒子里把一个苹果拿了出来,但是你没有记下来你是从哪个盒子拿出来的,盒子这么多,那你吃了一口以后,想放回去也是不可能的了,这样对于数据来说是很不安全的,所以肯定不能让你直接拿走这个苹果,只能让你复制一个苹果走,因为你不知道盒子编号,肯定是还不回来了。

五、启发

  1. 要清楚意识到在计算机中存储的值本身是没有属性的,只是我们人为定义,才加上了属性,无论是变量的值,还是地址的值,还是不同类型的值,都是一样存在计算机内外存中的。
  2. 要熟悉掌握4个解释,清楚几个基本符号之间的关系。
  3. 分析的时候,要习惯把符号和字符分开或者合并理解。
  • 9
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼月半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值