2015-10-06 2 views
0

Я написал это, чтобы проверить свои знания на указателях:Почему эта программа имеет неожиданные значения указателя?

int main(){ 
    int seven = 7; 
    int* p = &seven; 
    int** pp = &p; 
    int*** ppp = &pp; 
    printf("%d %d %d %d\n", *ppp, &pp, &p, &seven); 
} 

Однако на выходе, я получаю:

1363848032 1363848024 1363848032 1363848044

Это неинтуитивное для меня, потому что *ppp == &p

Я ожидая *ppp == &pp. Почему это происходит? Соответствует ли &pp указателю на p?

+3

всегда использует спецификатор формата '"% p "' для печати адресов указателей! также возвращаем что-то из основного (так как он должен возвращать 'int'), чтобы быть педантичным, возвращать' EXIT_SUCCESS' из 'stdlib.h' и, наконец, не в последнюю очередь, eather писать' int main (void) 'или' int main (int argc, const char * argv []) ' –

+1

Yessir, будет делать в будущем @PeterVaro –

ответ

3

Я попытаюсь объяснить проблему со следующей схемой:

ppp  pp  p seven  <---- variable names 
+----+ +----+ +----+ +----+ 
| 30 | | 20 | | 10 | | 7 |  <---- memory contents 
+----+ +----+ +----+ +----+ 
    40  30  20  10  <---- memory addresses 

В приведенной выше схеме коробки представляют собой отдельные слоты памяти, в которых переменные хранятся. Число под каждым из этих полей является адресом этого места в памяти.

Теперь указатель действительно представляет собой переменную, значение которой является числом, которое является адресом памяти какой-либо другой переменной. Итак, когда вы говорите *ppp, вы запрашиваете значение переменной, которое по адресу 30, которое равно 20, которое является адресом p. Таким образом, вы получаете *ppp == &p и ppp == &pp.

+0

Ницца, это делает его очень понятным, спасибо! –

1
int*** ppp = &pp; 

Итак, почему вы ожидаете *ppp == &pp? (обратите внимание на дополнительные * разыменования)

+0

Не должно ли значение' ppp' быть добавлением 'pp'? И поэтому при разыменовании '* ppp == (addr pp)'? –

+0

Вы не желаете разыгрывать значение чего-то .... Если 'ppp' имеет значение, чтобы его получить, вы пишете' ppp' .... –

+2

@ ylun.ca 'ppp == & pp', поэтому '* ppp == * (& pp)' – Barmar

1

Вы пытаетесь сделать что-то вроде этого?

#include <stdio.h> 

int main(){ 
    int seven = 7; 
    int* p = &seven; 
    int** pp = &p; 
    int*** ppp = &pp; 

    printf("%d %d \n", *p, seven); 
    printf("%d %d \n", **pp, seven); 
    printf("%d %d \n", ***ppp, seven); 


    printf("%p %p \n", p, &seven); 
    printf("%p %p \n", pp, &p); 
    printf("%p %p \n", ppp, &pp); 
    printf("%p %p \n", *ppp, pp); 

} 


     $ ./ptr 
     7 7 
     7 7 
     7 7 
     0x7ffe4dce54b4 0x7ffe4dce54b4 
     0x7ffe4dce54a8 0x7ffe4dce54a8 
     0x7ffe4dce54a0 0x7ffe4dce54a0 
     0x7ffe4dce54a8 0x7ffe4dce54a8 
1

Есть простой способ взглянуть на это: Коробки и номера ящиков. Вы можете поместить все виды чисел в коробки, включая номера ящиков.

В вашем примере:

7 помещают в коробку (переменная seven), который имеет ряд коробочную &seven.

Затем вы создаете новую коробку (переменная p) для хранения 7 «s номер ящика (&seven), который, в свою очередь, имеет ряд коробочную &p.

Позже вы сделаете то же самое и так далее.

ppp трюмов номер ящика s, который был создан для хранения p 'pp номер ящика s, который в свою очередь был создан, чтобы держать seven «s номер ящика.

*ppp = pp 
*pp = p 
*p = seven = 7 
Смежные вопросы