【问题标题】:Tricky pointer question棘手的指针问题
【发布时间】:2011-03-28 22:45:57
【问题描述】:

我在从这个链接中找到的关于 c 指针的过去考试问题中遇到了问题, http://www.cl.cam.ac.uk/teaching/exams/pastpapers/y2007p3q4.pdf

问题是这样的:

一个 C 程序员正在使用一个 8 位的小端机器 字节和一个字中的 4 个字节。这 编译器支持非对齐访问和 使用 1、2 和 4 个字节来存储 char, 分别是short和int。这 程序员写了以下 定义(右下方)访问 主内存中的值(左下):

地址字节偏移
----------0 --1-- 2-- 3
0x04 | 10 00 00 00
0x08 | 61 72 62 33
0x0c | 33 00 00 00
0x10 | 78 0c 00 00
0x14 | 08 00 00 00
0x18 | 01 00 4c 03
0x1c | 18 00 00 00

int **i=(int **)0x04;  
short **pps=(short **)0x1c;  

struct i2c {  
int i;  
char *c;  
}*p=(struct i2c*)0x10;

(a) 写下下列 C 表达式的值:

**i  
p->c[2]  
&(*pps)[1]  
++p->i  

我明白了

**i == 0xc78  
p->c[2] == '62'  
++p->i == 0x1000000  

我不明白第三个问题(&(*pps)[1]),有人可以解释一下这里发生了什么吗?我知道 pps 指针已被取消引用,但随后运算符的地址已应用于该值。这不就像询问常量的地址吗,例如如果我这样做了

int i = 7;  
int *p = &i;
&(*p)   //would this mean address of 7??  

提前感谢您的帮助。

【问题讨论】:

  • 他们为什么要问这些东西而不是教有用的、干净的编程?
  • 我很高兴其他人也这么认为。我还要感谢大家为提供快速简洁的答案所做的努力。这对我来说更清楚。

标签: c pointers


【解决方案1】:

[] 运算符优先于 & 运算符。因此代码取消引用pps 以获取short* 数组的第一个元素。由于该元素也是一个指针,我们可以将其视为一个数组并查找它所指向的右侧的元素,即[1]。最后,我们获取该元素的地址。

注意&p[i]p + i 相同可能很有用 - 它为您提供指向p 指向右侧的元素i 位置的指针。

中间值为:

pps == 0x1c
*pps == 0x18
&(*pps)[1] == *pps + 1 == 0x1A

+1 增加了两个字节,因为它用于short*

【讨论】:

  • 投反对票的人能否指出我的错误,以便我改正?
  • +1 大约 20 分钟我认为你完全错了(虽然没有拒绝投票)但你的价值观对我来说似乎很好
  • +1 谢谢你,我总是忘记优先顺序并最终尝试从左到右评估事物。
  • @ricola86:在这种情况下,让我建议您彻底阅读C++ operator precedence chart :-)
  • @MByD:公平地说,大约五分钟后,最后一个数字是0x20 而不是0x1A,所以我在某些时候错了:-)
【解决方案2】:

表达式被解析为&((*pps)[1])pps 被视为指向数组的指针,您正在访问该指向数组的第一个元素,然后获取该元素的地址。

【讨论】:

    【解决方案3】:

    pps是指向short的指针,

    这意味着*pps是一个指向short(或shorts数组)的指针,

    (*pps)[1] 就像*(*pps + 1) [指针算术],

    &(*(*pps + 1))*(*pps+1)的地址,

    或者,换句话说 - (*pps+1)(它是一个指向short的指针)。

    【讨论】:

      【解决方案4】:

      pps 是一个指向指针的指针。 它正在取消引用pps。所以现在你有一个指针。由于数组只是指针,因此您将 pps 用作数组。

      那么就等于:

      short ps[2] = {0x0001,0x034c};
      short **pps = &ps;
      

      所以结果是:0x034c

      【讨论】:

      • 否:(*pps)[1] 是 0x034c。 &(*pps)[1] 是 0x1a。
      • 是的,你右边的指针地址是0x1a。 (23:30缺乏理解能力):)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 2011-07-19
      • 1970-01-01
      • 2011-05-07
      • 2013-02-08
      • 2011-10-26
      相关资源
      最近更新 更多