Значение может меняться, потому что то, что вы делаете постоянным, указывает на то, на что указывает указатель, а не на то, что внутри него.
Позвольте мне дать вам возможность подумать об этом, что является хорошей иллюстрацией, но не должно быть буквальным. Тип указателя можно рассматривать как целое число без знака (вероятно, 32 или 64 бита в длину, но это не имеет значения прямо сейчас). В действительности все, что когда-либо хранится в указателе, представляет собой целое число без знака или Nil, которое для наших целей мы будем называть «ноль».
Если вы указали указатель на константу таким образом, вы делаете то, что это обычно означает; содержимое этой переменной является постоянным. Таким образом, число, попадающее в это целое без знака, не изменится.
Однако, если указатели используются (или разыменовываются), они являются особыми в том смысле, что значение указателя используется для ссылки на другое место памяти. Это место является еще одной переменной. Поскольку ваше задание не изменяет собственно указатель, оно полностью действует. :)
Точно так же уличный адрес дома не изменение, когда оно продается, и новые жители перемещаются. Тот же дом, разные жители. –
Вы действительно хотели 'const int * ptr = & a;' или, может быть, 'const int * const ptr = & a;'. –
«Удержание адреса ptr не изменяется, так как может значение, которое ptr указывает на изменение» - точно. они ортогональны. Адрес, который имеет указатель, не имеет ничего общего с содержимым объекта, на который он указывает. –