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

184 Глава 4

Выражение (sizeof pstr) / (sizeof pstr [0] ) делит число байт, занятых масси- вом указателей на число байт, занятых первым его элементом. Поскольку каждый эле- мент массива занимает одно и то же место в памяти, в результате получается число элементов массива.

Помните, что pstr — это массив указателей. Применение операции sizeof ко всему мас- сиву или отдельным его элементам ничего не скажет нам о памяти, занятой текстовыми строками.

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

переменная size получает значение 4. Эта переменная объявлена с типом size_t, чтобы обеспечить соответствие типу значения, которое возвращает операция sizeof. Использование другого целочисленного типа для этой переменной может привести к появлению предупреждающих сообщений компилятора.

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

Описание полученных результатов

Как видите, необходимое изменение в этом примере очень простое. Мы вычисля- ем количество элементов в массиве указателей pstr и сохраняем результат в перемен- ной count. Затем везде, где было указано общее количество элементов массива (6), мы просто вставляем переменную count. Теперь вы можете добавлять новые имена в список счастливых звезд, и программа "подгоняется" автоматически.

Константные указатели и указатели на константы

Очевидно, что массив pstr в последнем примере не предназначен для того, чтобы быть модифицированным, как не должны модифицироваться строки, на которые ука- зывают его элементы, как и не должна модифицироваться переменная count. Было бы неплохо каким-то образом гарантировать, чтобы все эти вещи не могли быть оши- бочно изменены в программе. Переменную count очень легко защитить от непредна- меренной модификации, написав так:

Однако массив указателей требует более тщательного рассмотрения. Массив объ- явлен следующим образом:

Каждый указатель в массиве инициализирован адресом строчного литерала — "Robert Redford", "Hopalong Cassidy" и так далее. Типом строчного литерала являет- ся массив const char, поэтому получается, что вы сохраняете адрес константного массива в не константном указателе. Причина, по которой компилятор позволяет использовать строчные литералы для инициализации элементов массива char *, за- ключается в необходимости обеспечения обратной совместимости с существующим кодом.

Если вы попытаетесь изменить символьный массив оператором вроде следующего:

то программа не скомпилируется.

Если вы сбросите один из элементов массива в указатель на символ посредством оператора:

то программа скомпилируется, но потерпит крах при выполнении этого оператора.

Конечно, вы не хотели бы получить непредсказуемое поведение программы, вро- де краха во время выполнения, и вы можете предотвратить его. Более удачный спо- соб написания объявления массива будет таким: