Подтвердить что ты не робот

Трудный указательный вопрос

У меня возникли проблемы с прошлым экзаменационным вопросом по указателям в 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??  

Заранее благодарим за любую помощь.

4b9b3361

Ответ 1

Оператор [] имеет приоритет над оператором &. Таким образом, код разыменовывает pps, чтобы перейти к первому элементу массива short*. Поскольку этот элемент также является указателем, мы можем рассматривать его как массив и искать элемент, расположенный справа от того, на что он указывает, wth [1]. Наконец, мы берем адрес этого элемента.

Может быть полезно отметить, что &p[i] совпадает с p + i - он дает вам указатель на позиции элемента i справа от того, где p указывает на.

Промежуточные значения:

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

(+1 добавляет два байта, поскольку используется на short*)

Ответ 2

Выражение анализируется как &((*pps)[1]); pps обрабатывается как указатель на массив, вы получаете доступ к первому элементу этого массива с указателем, а затем берете адрес этого элемента.

Ответ 3

pps является указателем на указатель на короткий,

что означает, что *pps является указателем на короткий (или массив шорт),

(*pps)[1] похож на *(*pps + 1) [арифметика указателей],

и &(*(*pps + 1)) - адрес *(*pps+1),

или, другими словами, (*pps+1) (который является указателем на короткий).

Ответ 4

pps - указатель на указатель. Это разыменование pps. Итак, теперь у вас есть указатель. Поскольку массивы - это просто указатели, вы используете pps в качестве массива.

Это то же самое, что и:

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

поэтому результат: 0x034c