Местоположение int *k
равно &k
, вот так:
// For this example, assume the variables start at 0x00 and are 32 bits each.
int A = 9; // 0x00 = 0x09
int * k = &A; // 0x04 = 0x00
int ** k_2 = &k; // 0x08 = 0x04
// Thus:
cout << "Value of A: " << A; // "Value of A: 9"
cout << "Address of A: " << k; // "Address of A: 0x00"
cout << "Address of k: " << k_2; // "Address of k: 0x04"
assert( A == *k);
assert(&A == k);
assert(&A == *k_2);
assert( A == **k_2);
assert( k == *k_2);
assert(&k == k_2);
Указатель - это переменная, 32-разрядная на 32-разрядных двоичных файлах и 64 на 64, хранящая адрес памяти. Как и любая другая переменная, она имеет собственный адрес и синтаксис идентичен. В большинстве случаев указатели действуют как целые числа без знака одинакового размера.
Теперь, когда вы берете &k
, у вас теперь есть int **
со всеми интересными сложностями, которые с этим связаны.
Из int ** k_2 = &k
, *k_2
- это k
, а **k_2
- это *k
, так что все работает так, как вы ожидаете.
Это может быть полезным способом управления кросс-библиотекой при создании объектов (указатели довольно фундаментальны и в большинстве случаев безопасны для передачи). Двойные указатели обычно используются в интерфейсах, где вы хотите передать указатель, который будет заполнен объектом, но не раскрывать, как создается объект (например, DirectX).