Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
A.doc
Скачиваний:
36
Добавлен:
09.04.2015
Размер:
5.6 Mб
Скачать

186 Глава 4

В этом случае устраняется противоречие между константностью строк, на кото- рые указывают элементы массива указателей и не константностью самих указателей. Если теперь попытаться изменить строки, компилятор обнаружит это и выдаст со- общение об ошибке во время компиляции.

Однако вы все еще можете написать такой оператор:

Те счастливчики, которые выберут мистера Редфорда (Redford), получат вместо него мистера Кессиди (Cassidy), поскольку оба указателя теперь указывают на одно и то же имя. Обратите внимание, что это не изменяет значения объектов, на кото- рые указывают указатели-элементы массива, но изменяет значение самого указателя, хранящегося в pstr [0]. Поэтому вы должны запрещать подобного рода изменения, поскольку некоторые люди считают, что старина Хоппи (Hopland Cassidy) не столь импозантен, как Роберт (Robert Redford). И сделать это можно с помощью следующе- го оператора:

Дабы подытожить все сказанное: необходимо различить три ситуации, связанные с константами, указателями и объектами, на которые они указывают:

  • указатель на константный объект;

  • константный указатель на объект;

  • константный указатель на константный объект.

В первой ситуации объект, на который указывает указатель, не может быть моди- фицирован, но можно установить указатель на что-нибудь другое:

Во второй ситуации адрес, сохраненный в указателе, не может быть изменен, но объект, на который он указывает, может:

И, наконец, в третьей ситуации как указатель, так и объект, на который он указы- вает, определены как константы, а потому никогда не могут быть изменены:

Конечно, все это касается указателей любого типа. Указатель на тип char использован нами исключительно для примера.

Указатели и массивы

Имена массивов в некоторых случаях могут вести себя как указатели. В большин- стве ситуаций, если вы используете имя одномерного массива само по себе, оно ав- томатически преобразуется в указатель на первый элемент этого массива. Обратите внимание, что это не касается того случая, когда имя массива выступает в качестве операнда sizeof.

Массивы, строки и указатели 187

Если имеются следующие объявления:

то вы можете написать такое присваивание:

Это присваивает адрес первого элемента массива data указателю pdata. Приме- нение имени массива самого по себе означает ссылку на его адрес. Если вы использу- ете имя массива data с индексным значением, то это означает ссылку на содержимое элемента, соответствующего значению индекса. Поэтому, если вы хотите сохранить адрес элемента в указателе, то должны использовать операцию взятия адреса:

Здесь указатель pdata получает адрес второго элемента массива.

Арифметика указателей

Над указателями можно выполнять арифметические операции. Правда, они огра- ничены только сложением и вычитанием, но можно также сравнивать значения ука- зателей, получая логический результат. Арифметика над указателями неявно предпо- лагает, что указатель указывает на массив, и арифметические операции выполняются над адресом, содержащимся в указателе. Так, например, указателю pdata можно при- своить адрес третьего элемента массива data с помощью следующего оператора:

В этом случае выражение pdata + 1 будет ссылаться на адрес data [ 3 ] — четверто- го элемента массива data, поэтому вы можете переставить указатель на этот элемент следующим образом:

Этот оператор увеличивает адрес, содержащийся в pdata, на количество байт, ко- торое занимает каждый элемент массива data. В общем случае выражение pdata + п, где п — любое целочисленное выражение, добавляет n*sizeof (double) к адресу, со- держащемуся в pdata, потому что pdata объявлен как указатель на double. Это про- иллюстрировано на рис. 4.8.