>// i - переменная типа int; p - указатель на тип int;
>// r - ссылка на тип int
>int i = 1024, *p = &i, &r = i;
Весьма распространенное заблуждение полагать, что модификатор типа (>*
или >&
) применяется ко всем переменным, определенным в одном операторе. Частично причина в том, что между модификатором типа и объявляемым именем может находиться пробел.
>int* p; // вполне допустимо, но может ввести в заблуждение
Данное определение может ввести в заблуждение потому, что создается впечатление, будто >int*
является типом каждой переменной, объявленной в этом операторе. Несмотря на внешний вид, базовым типом этого объявления является >int
, а не >int*
. Символ >*
— это модификатор типа >p
, он не имеет никакого отношения к любым другим объектам, которые могли бы быть объявлены в том же операторе:
>int* p1, p2; // p1 - указатель на тип int; p2 - переменная типа int
Есть два общепринятых стиля определения нескольких переменных с типом указателя или ссылки. Согласно первому, модификатор типа располагается рядом с идентификатором:
>int *p1, *p2; // p1 и p2 — указатели на тип int
Этот стиль подчеркивает, что переменная имеет составной тип. Согласно второму, модификатор типа располагается рядом с типом, но он определяет только одну переменную в операторе:
>int* p1; // p1 - указатель на тип int
>int* p2; // p2 - указатель на тип int
Этот стиль подчеркивает, что объявление определяет составной тип.
В этой книге используется первый стиль, знак >*
(или >&
) помещается рядом с именем переменной.
Теоретически нет предела количеству модификаторов типа, применяемых в операторе объявления. Когда модификаторов более одного, они объединяются хоть и логичным, но не всегда очевидным способом. В качестве примера рассмотрим указатель. Указатель — это объект в памяти, и, как у любого объекта, у этого есть адрес. Поэтому можно сохранить адрес указателя в другом указателе.
Каждый уровень указателя отмечается собственным символом >*
. Таким образом, для указателя на указатель пишут >**
, для указателя на указатель на указатель — >***
и т.д.
>int ival = 1024;
>int *pi = &ival; // pi указывает на переменную типа int
>int **ppi = π // ppi указывает на указатель на переменную типа int
Здесь >pi
— указатель на переменную типа int, a >ppi
— указатель на указатель на переменную типа. Эти объекты можно было бы представить так:
Подобно тому, как обращение к значению указателя на переменную типа >int
возвращает значение типа >int
, обращение к значению указателя на указатель возвращает указатель. Для доступа к основной объекту в этом случае необходимо обратиться к значению указателя дважды:
>cout << "The value of ival\n"
> << "direct value: " << ival << "\n"
> << "indirect value: " << *pi << "\n"
> << "doubly indirect value: " << **ppi << endl;