Как двойной указатель действительно ведет себя так? - PullRequest
0 голосов
/ 05 апреля 2019

Не правда ли, что адрес двойного указателя хранит только указатель ?Как тогда можно хранить целочисленный адрес?

{
    int **ptr,a;
    a = 10;
    ptr = &a; 

    printf("value of a = %d\n",*ptr);  //why it works?
    printf("value of a = %d\n",**ptr); //why it doesnt work?

}

Ответы [ 2 ]

6 голосов
/ 05 апреля 2019

Что касается вашей проблемы, поскольку вы указываете ptr на &a, то выполнение *ptr приведет к тому же результату, что и *(&a), что дает вам значение, на которое указывает &a, что это значение a. Хотя это семантически неверно и может привести к другим проблемам, если размер int * (который на самом деле *ptr) отличается от размера int (что и есть a).

Когда вы делаете **ptr, вы обрабатываете значение a как указатель и разыменовываете его. Поскольку 10 вряд ли будет действительным указателем на современном ПК, вы получите неопределенное поведение .


Вы говорите "двойной адрес указателя в хранилище указателя", и это правильно. Указатель на указатель может хранить адрес (указатель) указателя. Но &a - это не адрес указателя, это адрес переменной без указателя a.

Чтобы "двойной указатель" (действительно указатель на указатель) работал, вам нужно что-то вроде

int a = 10;
int *ptr = &a;  // Make ptr point to the variable a
int **ptrptr = &ptr;  // Make ptrptr point to the variable ptr

После этого *ptrptr == ptr и **ptrptr == *ptr и **ptrptr == a.

Несколько графически выше можно увидеть что-то вроде

+--------+     +-----+     +---+
| ptrptr | --> | ptr | --> | a |
+--------+     +-----+     +---+
0 голосов
/ 05 апреля 2019

Не правда ли, что двойной указатель хранит адрес только указателя?

Нет. Указатель любого типа может хранить адрес чего угодно. Но в идеале программист должен убедиться, что в нем хранится адрес действительного типа.

Делая ptr = &a;, вы сохраняете адрес целого числа в переменной двойного указателя.

printf("value of a = %d\n",*ptr);  //why it works?

*ptr вернет значение по адресу, сохраненному в ptr. Поскольку сохраненный адрес имеет целочисленную переменную, он возвращает целочисленное значение. Но обратите внимание, что возвращаемое значение будет иметь тип адреса, поскольку ptr является двойным указателем. Однако в printf() вы используете %d для печати значения. Таким образом, значение типа указателя, возвращаемое *ptr, будет приведено к целому числу и напечатано Таким образом, вы получите правильный вывод.

printf("value of a = %d\n",**ptr); //why it doesnt work?

Это не работает, потому что это эквивалентно (*(*ptr)). Итак, вы пытаетесь прочитать целочисленное значение, хранящееся по адресу 10. Я думаю, что это либо недопустимый адрес на вашем компьютере, либо ваша программа не имеет разрешения на чтение этого адреса.

PS: Вы должны получать предупреждения компилятора. Они дают некоторые подсказки.

...