При указании размера массива убедитесь, что количество элементов, по меньшей мере, на единицу больше длины строки (не забывайте о нулевом символе). Любые неиспользованные элементы инициализируются значением 0 (которое представляет собой нулевой символ в форме char). На рис. 11.1 приведена иллюстрация.

Рис. 11.1. Инициализация массива
Часто удобно предоставить определение размера массива компилятору; вспомните, что если размер не указан в инициализирующем объявлении, компилятор самостоятельно определит этот размер:
const char m2[] = "Если вам не о чем думать, вообразите что-нибудь.";
Инициализация символьных массивов — один из тех случаев, когда действительно имеет смысл позволить компилятору определять размер массива. Причина в том, что функции обработки массивов не нуждаются в знании размера массива, т.к. они могут просто находить нулевой символ, отмечающий конец.
Предоставление компилятору возможности вычислить размер массива самостоятельно работает только при инициализации массива. Если вы создаете массив, который намерены заполнить позже, его размер необходимо указывать в объявлении.
Символьные строки и строковые функции 423
Внутри объявления размер массива должен вычисляться как целочисленное значение. До ввода стандартом С99 массивов переменной длины (variable length array — VLA) размер должен был быть целочисленной константой, что включает возможность применения выражения, образованного из константных целочисленных значений.
int n = 8;
char cookies [1]; //допустимо
char cakes[2 + 5]; //допустимо, поскольку размер является константным выражением
char pies[2*sizeof(long double) + 1]; // допустимо
char crumbs[n]; // не допускалось до выхода стандарта С99;
// в С99 это массив переменной длины
Подобно любому имени массива, имя символьного массива выдает адрес первого элемента массива. Следовательно, приведенное ниже утверждение справедливо:
char car[10] = "Луна";
car == &car[0], *car== 'Л' и *(car + l) == car[1] == 'у'
Действительно, для установки строки можно использовать форму записи с указателями. Например, в листинге 11.1 имеется следующее объявление:
const char * ptl = "Что-то указывает на меня.";
Это объявление очень близко к такому объявлению:
const char arl[] = "Что-то указывает на меня.";
Оба объявления говорят о том, что ptl и arl являются адресами строк. В обоих случаях строка, заключенная в кавычки, сама определяет необходимый объем памяти, который будет для нее зарезервирован. Тем не менее, эти формы не идентичны.
Массивы или указатели
Так в чем же разница между формами в виде массива и указателя? Запись в форме массива (arl[]) приводит к размещению в памяти компьютера массива из 26 элементов (по одному на каждый символ плюс один элемент для завершающего символа ‘\0'). Каждый элемент инициализируется соответствующим символом строкового литерала. Обычно строка, заключенная в кавычки, хранится в сегменте данных, который является частью исполняемого файла; когда программа загружается в память, вместе с ней загружается и эта строка. Говорят, что заключенная в кавычки строка находится в апатической памяти. Однако память под массив выделяется только после того, как программа начнет выполнение. В это время строка, заключенная в кавычки, копируется в массив. (В главе 12 управление памятью обсуждается более подробно.) Обратите внимание, что в этот момент существуют две копии строки. Одна — это строковый литерал в статической памяти, а другая — строка, хранящаяся в массиве arl.
В дальнейшем компилятор будет распознавать имя массива arl как синоним адреса первого элемента массива, &arl [0]. Один важный аспект состоит здесь в том, что в форме массива arl является адресной константой. Значение arl изменять нельзя, т.к. это означало бы изменение места (адреса), где хранится массив. Для идентификации следующего элемента в массиве можно задействовать операции наподобие arl + 1, но выражение ++arl не разрешено. Операция инкремента может применяться только к именам переменных (или, в общем смысле, к модифицируемым 1-значениям), но не к константам.
Форма указателя (*ptl) также приводит к тому, что в статической памяти под строку резервируются 26 элементов. Вдобавок, как только программа начнет выполня ться, она выделяет в памяти место под переменную типа указателя ptl и сохраняет в пей адрес строки. Первоначально эта переменная указывает на первый символ строки, но
Читать дальше