Я ожидал, что & 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
.