我在使用此链接找到的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??
提前感谢您的帮助。
答案 0 :(得分:7)
[]
运算符优先于&
运算符。因此代码解除引用pps
以获取short*
数组的第一个元素。由于此元素也是一个指针,我们可以将其视为一个数组,并在元素的一个位置向上查找它所指向的位置,[1]
。最后,我们采用该元素的地址。
注意&p[i]
与p + i
相同可能会有用 - 它会为您提供指向i
点所在位置的元素p
位置的指针到。
中间值为:
pps == 0x1c
*pps == 0x18
&(*pps)[1] == *pps + 1 == 0x1A
(+1
添加两个字节,因为它用于short*
)
答案 1 :(得分:1)
表达式被解析为&((*pps)[1])
; pps
被视为指向数组的指针,您正在访问该指向数组的第一个元素,然后获取该元素的地址。
答案 2 :(得分:1)
pps
是指向short的指针,
这意味着*pps
是指向short(或短数组)的指针,
(*pps)[1]
就像*(*pps + 1)
[指针算术],
和&(*(*pps + 1))
是*(*pps+1)
的地址,
或换句话说 - (*pps+1)
(指向简短的指针)。
答案 3 :(得分:0)
pps是指向指针的指针。 它正在取消引用pps。所以现在你有一个指针。由于数组只是指针,因此您将pps用作数组。
它与:
相同short ps[2] = {0x0001,0x034c};
short **pps = &ps;
所以结果是:0x034c