×
Traktatov.net » Язык программирования C++. Пятое издание » Читать онлайн
Страница 48 из 714 Настройки

>// 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;