Изменение Значения Указателя

#c #pointers

Вопрос:

Действительно глупый вопрос, но я очень смущен.

Итак, я понимаю, что если у вас есть:

 int i(3); intamp; j(i); int* k(amp;i);  

В этом случае, если значение j изменится, то значение i также изменится, потому j что в основном это псевдоним i ? С другой стороны, если мы k укажем на что-то другое, то ценность i и j вовсе не изменится, верно?

Если вышесказанное верно, то, если у нас есть:

 a = 1; b = 2; p = amp;a; q = amp;b; *p = *q;  

Тогда почему значение a изменяется на 2? Я думал p , что это просто указывает на что-то другое, и это не изменяет значения a ?

Ответ №1:

Гипотеза 1 верна.

До тех пор, пока k будет указано i (и, кстати int* k(amp;j); , также будет указано k , i потому j что ЕСТЬ i ) *k=10; , будет установлено i значение 10 . Если вы укажете k куда-то еще, то *k=10; изменится все, на что он сейчас указывает.

Но во второй части никогда ничего не меняется p , от a чего можно было бы отмахнуться , так что написание *p изменится a . q полностью отделен от p , поэтому указание q на b просто означает q , что указывает на b и *p = *q; эффективно a=b изменяется там, где указывает любой из этих указателей, и вы получите другой результат.

Ответ №2:

В вашем первом примере i это переменная с рядом свойств — два из них-адрес в памяти и имя ( i ). j является псевдонимом i , поэтому это просто альтернативное имя для той же ячейки памяти i , что и . Или, другими словами, базовая ячейка памяти имеет два имени — одно имя есть i , а другое есть j .

Любые операции, которые влияют на базовую память, одновременно изменяют значения обоих i и j . Таким образом , присвоение i влияет (через ячейку памяти) на значение j , и наоборот. Например, i = 42 будет работать путем изменения содержимого базовой ячейки памяти и, поскольку j это альтернативное имя для той же ячейки памяти, приведет к тому, что условие j == 42 будет истинным, и наоборот.

k является переменной, которая содержит адрес i (т. е. адрес базовой ячейки памяти). Назначение *k влияет на место в памяти, поэтому изменяется i и, следовательно j . Например, *k = 21 заставит i == 21 amp;amp; j == 21 быть правдой.

Одно из ключевых различий между указателем и ссылкой заключается в том, что указатель может быть переназначен (поэтому он содержит адрес другой ячейки памяти), но ссылка не может. Таким образом, невозможно связать ни i то, ни другое, ни j с другой ячейкой памяти. Принимая во внимание, что назначение k = amp;some_other_int приведет k к тому, что адрес будет содержать some_other_int — и k больше не будет иметь никакой связи с i или j . Выполнение каких-либо *k действий повлияет на область памяти , в которой есть имя some_other_int , но не на значения, связанные с i или j .

В вашем втором примере значение p -это адрес a , а значение q -это адрес b . Однако выражение *p = *q работает, извлекая значение в ячейке памяти, на которую указывает by q (т. Е. значение b ), и присваивая его в ячейку памяти, на которую указывает by p (которая имеет имя a ). Так *p = *q что имеет тот же чистый эффект, *p = b что и или a = b или даже a = *b . В этом смысле *p и *q могут рассматриваться как ссылки на (или альтернативные имена или псевдонимы) a и b соответственно.