В примере объявляется двумерный массив р, размером 4 строки на 3 столбца, элементы первой строки инициализируются единицами, второй строки — двойками и т. д. Обратите внимание на то, что списки инициализаторов двух последних строк содержат в конце запятую. За последним списком инициализаторов (4,4,4,) также стоит запятая. Эти дополнительные запятые не требуются, но допускаются. Требуются только те запятые, которые разделяют константные выражения и списки инициализаторов. Если список инициализаторов не имеет вложенной структуры, аналогичной структуре объекта составного типа, то элементы списка присваиваются элементам объекта в порядке следования. Поэтому вышеприведенная инициализация эквивалентна следующей:
int p[4][3] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
При инициализации объектов составных типов нужно внимательно следить за правильностью расстановки фигурных скобок в списках инициализаторов. В следующем примере этот вопрос иллюстрируется более детально.
Пример 2.
struct {
int n1, n2, n3;
} nlist[2][3] = {
{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}), /* строка 1 */
{{10,11,12}, {13,14,15}, {15,16,17}} /* строка 2 */
}
В примере переменная nlist объявляется как двумерный массив структур, состоящий из двух строк и трех столбцов. Каждая структура содержит три элемента. В строке 1 значения присваиваются первой строке массива nlist следующим образом:
1) Первая левая фигурная скобка строки 1 информирует компилятор языка Си о том, что начинается инициализация первой строки массива nlist (т. е. nlist[0]).
2) Вторая левая фигурная скобка означает, что начинается инициализация первого элемента первой строки массива (т. е. nlist[0][0]).
3) Первая правая фигурная скобка сообщает об окончании инициализации структуры nlist[0][0]. Следующая левая фигурная скобка сообщает о начале инициализации второго элемента первой строки nlist[0][1].
4) Процесс инициализации элементов подмассива nlist[0] продолжается до конца строки 1 и заканчивается по последней правой фигурной скобке.
Аналогично, в строке 2 присваиваются значения второй строке массива nlist, т. е. nlist[1].
Следует понимать, что фигурные скобки, охватывающие инициализаторы строки 1 и строки 2, необходимы. Следующая конструкция, в которой внешние фигурные скобки опущены, неверна.
struct {
int n1, n2, nЗ;
} nlist[2][3] = {
{1, 2, 3}, {4, 5, 6), {7, 8, 9),/* строка 1 */
{10,11,12), {13,14,15}, {16,17,18} /* строка 2 */
};
В этом примере по первой левой фигурной скобке в строке 1 начинается инициализация подмассива nlist[0], который является массивом из трех структур. Значения 1, 2, 3 назначаются трем элементам первой структуры (nlist[0][0]). Когда встретится правая фигурная скобка (после значения 3), инициализация подмассива nlist[0] закончится и две оставшиеся структуры — nlist[0][1] и nlist[0][2] — будут по умолчанию инициализированы нулевыми значениями. Аналогично, список {4,5,6} инициализирует первую структуру во второй строке nlist (т. е. nlist[1][0]), а оставшиеся две структуры — nlist[l][l] и nlist[1][2] — по умолчанию инициализируются нулевыми значениями. Когда компилятор языка Си обнаружит следующий список инициализаторов {7,8,9), он попытается инициализировать подмассив nlist[2]. Однако, поскольку nlist содержит только две строки и элемента nlist[2] в нем не существует, будет выдано сообщение об ошибке.
Пример 3.
union {
char m[2][3];
int i, j, k;
} y = {
{'1'},
{'4'}
};
В третьем примере инициализируется переменная у типа объединение. Первым элементом объединения является массив; он и будет инициализироваться. Список инициализаторов {'1'} задает значения для первой строки массива (m[0]). Поскольку в списке всего одно значение, то только первый элемент строки массива — m[0][0] —инициализируется символом '1', а оставшиеся два элемента в строке инициализируются по умолчанию нулевыми значениями (символом '\0'). Аналогично, первый элемент второй строки массива m инициализируется значением '4', а остальные элементы инициализируются по умолчанию нулевыми значениями.
Строковые инициализаторы
Существует специальная форма инициализации массива типа char — с помощью символьной строки. Например, объявление
char code[] = "abc";
инициализирует массив
Если в объявлении размер массива указан, а длина инициализирующей строки превышает указанный размер, то лишние символы отбрасываются. Следующее объявление инициализирует трехэлементный массив
char code[3] = "abcd";
В примере только три первые символа инициализатора заносятся в массив
Если инициализирующая строка короче, чем специфицированный размер массива, то оставшиеся элементы массива инициализируются нулевым значением (символом '\0').
Символьной строкой можно инициализировать не только массив типа char, но и указатель на тип char. Например, в объявлении
char *ptr = "abcd";