请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

//*pp=>p;问题

老师您好:
发现您一处错误:
今天看到后面的时候,就指针方面,发现逻辑上有矛盾就又回看,自己研究了一套模型来研究指针。如图:您第十八行(7-1集7:35)有一处错误,算是口误,但是影响挺大的,您说*pp等价于p,这貌似是不对的,应该是※pp这个地址位置,这块内存的名字叫p,或者说,p这块内存的地址是※pp,参考计算机的原理(源自打点计算机)。然后的话,如果可以的话,您能不能以后难的点,能够用模型画图来演示一下啥的,光说而且说的很快的时候,感觉有时候就可能会有问题[/?],小小的建议。我是初学者,如果说的不对还请指正。图片描述

正在回答

5回答

先上结论:

//img1.sycdn.imooc.com//szimg/5fea5823098b4f0607650168.jpg

再说下这是为什么。

按照定义,pp 指向了变量 p,因此 pp 里面存的是 p 的地址。

*pp 是取 pp 指向的变量的值,或者说取间接引用,结果就是 p 的值,因此 *pp 等价于 p。


从你的描述,感觉没有明白 `*pp` 这个运算? 这个其实就是从前面的 `*p` 和 a 的关系推出来的:

//img1.sycdn.imooc.com//szimg/5fea58d40998b80604350194.jpg

0 回复 有任何疑惑可以回复我~
  • 提问者 十三山入秋 #1
    非常感谢!
    回复 有任何疑惑可以回复我~ 2020-12-29 10:27:52
bennyhuo 2020-12-29 11:18:31

有问题欢迎继续探讨哈~也可以加群聊

1 回复 有任何疑惑可以回复我~
  • 提问者 十三山入秋 #1
    嗯嗯,[/露出热爱技术的微笑]
    回复 有任何疑惑可以回复我~ 2020-12-29 12:30:05
bennyhuo 2020-12-29 11:07:36

//img1.sycdn.imooc.com/szimg/5fea9d0009f5645317120463.jpg

我明白你混淆的点了,其实 * 在声明和运算的时候是不同的含义,参见上图的注释。

我这里说 *pp 等价于 p,讲的时候是有个上文的,就是

//img1.sycdn.imooc.com//szimg/5fea9d470985338912620647.jpg

0 回复 有任何疑惑可以回复我~
  • 提问者 十三山入秋 #1
    嗯:声明和运算的时候是不同的含义
    emmm...私又有新问题问题,看您的写法,这个int *和int ** 不是变量的修饰符吗?下面写成 size of(int *)
    关于  int *p=&a  和   int **pp=&p   的理解,我的理解就是,此二者描述的“左侧变量”分别是p和pp。
    代码书写的目的在于,语义表达,和逻辑闭环
    int *p=&a  语义是声明了指针变量p,其值为a的地址值(总归就是一个值),
    int **pp=&p  语义是声明了指针变量pp,特殊的地方在于pp的值是指针变量的地址(其实也无所谓,也是一个字面值)
    
    但是,老师,您int *(*pp)=&p,这种写法,就有点迷惑了[/挠头],左侧的 主角还是pp吧?记得之前您写过一个强转如:(int *)100,
    
    声明的时候,int p,加个星,int *p表示p是指针类型变量,*(*p)表示指针类型的指针类型,也说得通,那么问题来了,之前有一个强转,(int **)100,这种写法貌似也可以,举例:int * *aa = (int **) 100;
    
    他这个就有点奇怪,声明的修饰词 其中一部分(就是*)和 变量本身划到一起,然后强转的时候,又可以写成(int *),
    
    那为什么不写成int (*100),这样写直接报错,这块设计的逻辑不明朗
    
    所以,int *和int **这两个,分别是不是一个整体呢,表示指针类型啥的
    回复 有任何疑惑可以回复我~ 2020-12-29 12:25:19
  • 所以你要区分声明类型和其他场景,类型强转的时候就不是声明类型了。
    
    你先把他当成一个整体去理解吧,不要纠结这些问题了先,后面慢慢就习惯了。
    回复 有任何疑惑可以回复我~ 2020-12-29 13:12:37
  • 提问者 十三山入秋 回复 bennyhuo #3
    嗯嗯,好吧
    回复 有任何疑惑可以回复我~ 2020-12-29 14:33:52
提问者 十三山入秋 2020-12-29 10:27:05

老师您好:

*p的这个运算,按我图的演绎,是很好理解和推导的。您也可以看一下我画的图。

您的结论是对的,但问题关键不在这里,问题在于int **pp=&p这个表达式的拆分:

之前理解是左边拆成int * 和*pp两部分,现在根据**pp=a这个反推,(int**)应该是一个整体,也就是说关于“指针的指针”这一语义,他是专门有一个描述符(int **)来描述的。如图是演绎过程。或许对于您来说这个(int **是一个整体)太普通,完全没有在意到这一点,?。

如图,关注我标了蓝色五角星的地方。

https://img1.sycdn.imooc.com//szimg/5fea8e600895ad2b13151600.jpg

/**
* 7-1 指针基础
*/
#include <stdio.h>
#include <io_utils.h>
int main(void) {
 int a = 10;
 int *p = &a;//
 int **pp = &p;

 printf("*p:\t%#x\n", *p);
 printf("a:\t%#x\n", a);
 printf("p:\t%#x\n", p);
 printf("*pp:\t%#x\n", *pp);
 printf("**pp:\t%#x\n", **pp);
 printf("pp:\t%#x\n", pp);
 printf("&p:\t%#x\n", &p);
 printf("&a:\t%#x\n", &a);
 return 0;
}

---------运行结果-----------

*p:     0xa

a:      0xa

p:      0x64fe14

*pp:    0x64fe14

**pp:   0xa

pp:     0x64fe08

&p:     0x64fe08

&a:     0x64fe14


0 回复 有任何疑惑可以回复我~
  • 哈哈哈,其实你把 int **p 拆成 int *(*p) 去理解,也没什么毛病。
    
      int *(*pp) = &p;
      PRINT_HEX(pp);
      PRINT_HEX(&p)
    
    你代码里甚至可以这么写,结果是一样的。
    
    你只需要明白一件事,在类型声明的时候的 * 和取间接引用的 * 是不同的意思就行了。
    
    int *(*pp)  这个能够成立, 正说明 int ** 并不是一个整体,你仔细观察一下下面的写法:
    
    int (a);
    int (*p);
    
    int *(p);
    int *(*p);
    回复 有任何疑惑可以回复我~ 2020-12-29 11:02:16
  • 提问者 十三山入秋 回复 bennyhuo #2
    哇,老师您是穿越了吗,哈哈哈哈,您一个小时之前发的和我刚刚发的,内容匹配上了,好神奇,哈哈哈
    强转的时候,写(int *)100,这个为什么(int *)又可以看成一个整体
    回复 有任何疑惑可以回复我~ 2020-12-29 12:29:01
提问者 十三山入秋 2020-12-28 23:52:14

老师:“应该是*pp这个地址位置,这块内存的名字叫p,或者说,p这块内存的地址是*pp

md语法,把*转换成斜体了”

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信