Двухуровневая адресация в С++
Напомним, что указатель - это переменная. А поскольку это переменая, то ее значение должно быть где-то записано. Таким образом, если мы создаем переменную и ссылаемся на нее посредством указателя, то адрес со ответствующей ячейки памяти (значение указателя) в свою очередь также является значением какой-то ячейки. У этой ячейки, очевидно, есть адрес. И тут возникает вопрос: а можно ли этот адрес присвоить в качестве значения указателю? Другими словами, можно ли создать указатель на указатель? Задача состоит в том, чтобы создать указатель, который будет ссылаться на переменную-указатель, которая ссылается на обычную переменную. Ситуацию поясняет рисунок (кликабельно).
В верхней части - схема стандартной, одноуровневой адресации: переменная-указатель через свое значение-адрес ссылается на обычную переменную. Нижняя часть рисунка иллюстрирует двухуровневую адресацию: на переменную ссылается указатель, а на этот указатель, в свою очередь, ссылается еще один указатель. Значением второго указателя является адрес ячейки, в которую записан адрес исходной переменной. Легко понять, что двухуровневая адресация не является верхом совершенства и по аналогии может быть трехуровневая, четырехуровневая и т.д. адреса ция. Однако сразу отметим, что адресация уровня больше двух на практике используется редко.
Для объявления переменной-указателя на указатель перед именем этой переменной указывают два оператора *. Каждый дополнительный уровень адресации означает наличие дополнительного оператора * в объявлении переменной-указателя. Например, командой int **q объявляется
переменная-указатель на указатель на целочисленное значение. Пример двухуровневой адресации представлен ниже.
#includeusing namespace std; int main(){ int n,*p,**q; p=&n; q=&p; n=100; (*p)+=5; (**q)--; cout << n << "\n"; cout << *p << "\n"; cout << **q << "\n"; cout << p << "\n"; cout << q << "\n"; return 0; }