Инициализация
Описатель может специфицировать начальное значение описываемого идентификатора. Инициализатор, начинающийся со знака =, есть выражение или список выражений, заключенных в фигурные скобки. Список может содержать вложенные подсписки.
инициализатор: = выражение = { список_инициализаторов }
= { список_инициализаторов , }
список_инициализаторов: выражение список_инициализаторов , список_инициализаторов { список_инициализаторов }
{ список_инициализаторов , }
Все выражения в инициализаторе статической или внешней переменной должны быть константными (см. КОНСТАНТНЫЕ ВЫРАЖЕНИЯ), или выражениями, которые сводятся к адресу уже описанной переменной, возможно сдвинутому на значение константного выражения. Автоматические и регистровые переменные можно инициализировать произвольными выражениями, включающими константы и описанные перед этим переменные и функции.
Явным образом не проинициализированные статические и внешние переменные имеют в начале работы программы нулевые значения. Явным образом не проинициализированные автоматические и регистровые переменные первоначально содержат мусор.
Если инициализатор относится к скаляру (указателю или объекту арифметического типа), он должен включать одно выражение, возможно, заключенное в фигурные скобки. Начальное значение объекта равно значению данного выражения; выполняются те же преобразования типа, что и при присваивании.
Если описываемая переменная является составной (то есть структурой или массивом), инициализатор должен быть заключенным в скобки списком_инициализаторов компонентов. Элементы списка разделяются запятыми и записываются в том же порядке, что и компоненты структуры или массива. Если составная переменная содержит составные компоненты, то для них рекурсивно применяется данное правило. Если в списке меньше элементов, чем компонентов в составной переменной, оставшиеся компоненты заполняются нулями. Инициализировать объединения и автоматические составные переменные не разрешается.
В некоторых случаях внутренние скобки { } могут быть опущены. Если элемент списка_инициализаторов представляет собой заключенный в скобки подсписок, он инициализирует компоненты составного подобъекта; не допускается, чтобы элементов в подсписке было больше, чем компонентов. Если же скобки опущены, то из списка берется столько элементов, сколько требуется для инициализации очередного компонента (простого или составного); оставшиеся элементы пойдут на инициализацию следующих компонентов составного объекта, частью которого является текущий компонент.
Наконец, еще одно сокращение позволяет инициализировать массив символов текстовой константой. В этом случае последовательные символы текстовой константы становятся начальными значениями элементов массива.
Например, конструкция
int x [] = {1, 3, 5};
описывает и инициализирует x как одномерный массив из трех элементов, поскольку размер массива не специфицирован и имеется список из трех выражений. Запись
float y [4] [3] = { {1, 3, 5}, {2, 4, 6}, {3, 5, 7}, };
- это инициализация с полным набором скобок; 1, 3 и 5 инициализируют первую строку массива y[0], а именно элементы y[0][0], y[0][1] и y[0][2]. Аналогично инициализируются две следующие строки. Инициализатор преждевременно заканчивается, поэтому y[3] инициализируется нулями. В точности тот же результат можно было бы получить при помощи инициализации
float y [4] [3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7, };
Здесь список_инициализаторов записан без внутренних скобок, поэтому для инициализации первой строки массива будут взяты три первых элемента списка. Аналогично, следующие три берутся для y[1] и затем для y[2]. Запись
float y[4][3] = { {1}, {2}, {3}, {4} };
инициализирует первый столбец y (считающегося двумерным массивом) и заполняет все остальное нулями.
Наконец, запись
char msg [] = "Syntax error on line %s\n";
описывает символьный массив, элементы которого инициализируются при помощи текстовой константы. В текстовую константу (ее длина совпадает с размером массива) входит и заключительный символ NUL, \0.