Иногда указатель может ссылаться на указатель, который ссылается на число. Это называется многоуровневой адресацией. Иногда применение таких указателей существенно усложняет программу, делает ее плохо читаемой и подверженной ошибкам. Рис. 5.3 иллюстрирует концепцию многоуровневой адресации. На рисунке видно, что значением "нормального" указателя является адрес объекта, содержащего нужное значение. В случае двухуровневой адресации первый указатель содержит адрес второго указателя, который содержит адрес объекта с нужным значением.
Многоуровневая адресация может иметь сколько угодно уровней, однако уровни глубже второго, т.е. указатели более глубокие, чем "указатели на указатели" применяются крайне редко. Дело в том, что при использовании таких указателей часто встречаются концептуальные ошибки из-за того, что смысл таких указателей представить трудно.
На заметку | Не следует путать многоуровневую адресацию с многоуровневыми структурами данных, использующими указатели, такими, например, как связные списки. Это фундаментально различные концепции. |
Переменная, являющаяся указателем на указатель, должна быть соответствующим образом объявлена. Это делается с помощью двух звездочек перед именем переменной. Например, в следующем операторе newbalance объявлена как указатель на указатель на переменную типа float:
float **newbalance;
Следует хорошо понимать, что newbalance — это не указатель на число типа float, а указатель на указатель на число типа float.
Указатель Переменная +--------+ +--------+ | Адрес |------->|Значение| +--------+ +--------+ Одноуровневая адресация Указатель Указатель Переменная +--------+ +--------+ +--------+ | Адрес |----->| Адрес |----->|Значение| +--------+ +--------+ +--------+ Многоуровневая адресация |
При двухуровневой адресации для доступа к значению объекта нужно поставить перед идентификатором две звездочки:
#include <stdio.h> int main(void) { int x, *p, **q; x = 10; p = &x; q = &p; printf("%d", **q); /* печать значения x */ return 0; }
Здесь p объявлена как указатель на целое, a q — как указатель на указатель на целое. Функция printf() выводит на экран число 10.