棘手的指针问题

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

问题是:

AC程序员正在使用一个小端机器,一个字节为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?? 

在此先感谢您的帮助。

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

注意&p[i]p + i相同可能是有用的 – 它给你一个指向i指向p指向的右边的元素的指针。

中间值是:

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

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

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

pps是指向short的指针,

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

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

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

或者,换句话说 – (*pps+1) (这是指向短的指针)。

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

它与以下相同:

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

所以结果是:0x034c