Мои указатели / адреса неверны независимо от того, что я пытаюсь - PullRequest
0 голосов
/ 02 января 2019

Вот что я пытаюсь:

int a,b;
int *ptr;

a = 123;
ptr = &a;
b = *ptr;

printf("&a is %p\n",&a);
printf("ptr points to %p\n",ptr);
printf("&ptr is %p\n",&ptr);
printf("&b is %p\n",&b);

Результаты:

&a is 0x7ffee01fc828
ptr points to 0x7ffee01fc828
&ptr is 0x7ffee01fc818
&b is 0x7ffee01fc820

Я ожидал, что & b покажет тот же адрес, что и & a ... Но это не так, поэтому я попытался:

int a,*b;
int *ptr;

a = 123;
ptr = &a;
b = ptr;

printf("&a is %p\n",&a);
printf("ptr points to %p\n",ptr);
printf("&ptr is %p\n",&ptr);
printf("&b is %p\n",&b);

Это все еще приводит к неожиданному адресу памяти для & b:

&a is 0x7ffee1cbd828
ptr points to 0x7ffee1cbd828
&ptr is 0x7ffee1cbd818
&b is 0x7ffee1cbd820

Может кто-нибудь помочь мне понять, почему я не могу получить & b, совпадающий с тем жеадрес как & ptr или & a?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Я ожидал, что & b покажет тот же адрес, что и & a…

Наличие такого ожидания означает, что у вас неправильная ментальная модель о том, как работают указатели и какова их семантика в Cязык программирования.Неверное представление о ключе, кажется, происходит в этих двух строках исходного фрагмента кода:

Сначала у вас есть

b = *ptr;

Эта строка переводится в * "скопировать содержимоепамять по адресу ptr в переменную b. "Переменная b никогда даже не соприкасается с самим указателем.Вы можете прекрасно переписать его с таким же эффектом в

int tmp = *ptr;
b = tmp;

Фактически, каждый современный компилятор C будет выдавать идентичный код для любого случая.

Вторая строка гдеу вас есть неправильное представление, это

printf("&b is %p\n",&b);

, в частности, эффекты получения адреса переменной b, то есть результат &b.b является полностью независимой переменной со своим собственным адресом. Этот адрес нельзя изменить! Единственное, что можно изменить в переменной - это ее значение.

Указатели тоже являются переменными, и да, указатель действительно имеет адрес.Значением указателя является адрес, на который он указывает.Но, как и любая переменная, вы не можете изменить адрес, где хранится переменная, и когда вы назначаете адрес указателю, вы меняете его значение.Следовательно, когда во втором фрагменте кода вы назначаете b = ptr;, вы копируете значение из ptr в b.После этого и ptr, и b указывают на один и тот же адрес, но эти два указателя являются двумя независимыми копиями одного и того же значения, где каждая копия помещается в другое место в памяти.Естественно, если взять адрес b, получится нечто иное, чем адрес ptr.

0 голосов
/ 02 января 2019

сейчас a, b и ptr - это 3 разные переменные (независимо от их типа)

Так что их адрес отличается.Вы получите те же значения, если не , взяв адрес переменных-указателей.

int a,*b;
int *ptr;

a = 123;
ptr = &a;
b = ptr;

printf("&a is %p\n",&a);
printf("ptr points to %p\n",ptr);
printf("b is %p\n",b);
...