После объявления переменных *
разыменовывает их.
Например, после объявления чего-то вроде int **a;
, при его использовании мы имеем:
**a
значение в значении в местоположениихранится в a
(что в конечном итоге является целым)
*a
значение в местоположении хранится в a
(это другое местоположение)
a
местоположение хранится в a
&a
местоположение самой a
Давайте посмотрим, почему не работает каждый из ваших примеров:
**q = otheraddress;
назначение местоположенияint ×
*q = *otheraddress;
назначение int для местоположения ×
Редактировать: Давайте рассмотрим эти два примера:
q = &otheraddress;
назначение местоположения дляместоположение ✓
*q = otheraddress;
присвоение местоположения местоположению ✓
Давайте посмотрим на это так:
Предположим, у нас есть:
int *a;
int **q;
для предотвращения ошибок сегментации в будущем, давайте сначала назначим некоторый адрес:
int t = 5
a = &t;
Давайте посмотрим на адресапосле q = &a
:
//first snippet
0x7fffc3a2b338 // &a
0x5596853c98c0 // a
5 // *a
0x7fffc3a2b340 // &q
0x7fffc3a2b338 // q
0x5596853c98c0 // *q
5 // **q
Как и ожидалось, &a
помещается в q
, а a
содержит &t
, поэтому **(&a)
и **(q)
будут содержать значение5.
Теперь давайте посмотрим на адреса после *q = a
:
//second snippet
0x7fffc3a2b338 // &a
0x5596853c98c0 // a
5 // *a
0x7fffc3a2b340 // &q
0x7fffc3a2b345 // q
0x5596853c98c0 // *q
5 // **q
Здесь a
помещается в *q
, а сам a
равен &t
,поэтому *(a)
и *(*q)
с обоими содержат значение 5.
Чтобы понять разницу, мы рассмотрим пример:
int b = 3;
a = &b;
Используя это после первого фрагмента, a
присвоен другой адрес, а q
был объявлен &a
(который не изменился), поэтому **(q)
имеет то же значение, что и **(&a)
, который теперь равен 3.
Это все равно, что сказать:
int a = 3;
int *b = &a;
a = 5; //even though a has changed, b retains its old value of &a, thus *(b) == *(&a) == 5
Однако во втором фрагменте *q
уже был объявлен как a
до того, как он изменился, поэтому, хотя a
теперь имеет новый адрес, адрес внутри *q
по-прежнемуне изменилсяТаким образом, попытка доступа к *(*q)
будет использовать старый адрес и снова даст нам 5.
Это все равно, что сказать:
int a = 3;
int b = a;
a = 5; //even though a has changed, b still retains it's old value of 3