#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
соответственно.