Мы до сих пор уже много раз упоминали инициализацию, новсегда мимоходом , среди других вопросов. Теперь, после тогокак мы обсудили различные классы памяти, мы в этом разделепросуммируем некоторые правила, относящиеся к инициализации. Если явная инициализация отсутствует, то внешним и ста-тическим переменным присваивается значение нуль; автомати-ческие и регистровые переменные имеют в этом случае неопре-деленные значения (мусор). Простые переменные (не массивы или структуры) можно ини-циализировать при их описании, добавляя вслед за именем знакравенства и константное выражение: INT X = 1; CHAR SQUOTE = '\''; LONG DAY = 60 * 24; /* MINUTES IN A DAY */ Для внешних и статических переменных инициализация выполня-ется только один раз, на этапе компиляции. Автоматические ирегистровые переменные инициализируются каждый раз при входев функцию или блок.В случае автоматических и регистровых переменных инициализа-тор не обязан быть константой: на самом деле он может бытьлюбым значимым выражением, которое может включать определен-ные ранее величины и даже обращения к функциям. Например,инициализация в программе бинарного поиска из главы 3 моглабы быть записана в виде BINARY(X, V, N) INT X, V[], N; { INT LOW = 0; INT HIGH = N - 1; INT MID; ... } вместо BINARY(X, V, N) INT X, V[], N; { INT LOW, HIGH, MID; LOW = 0; HIGH = N - 1; ...} По своему результату, инициализации автоматических перемен-ных являются сокращенной записью операторов присваивания.Какую форму предпочесть - в основном дело вкуса. мы обычноиспользуем явные присваивания, потому что инициализация вописаниях менее заметна.Автоматические массивы не могут быть инициализированы. Внеш-ние и статические массивы можно инициализировать, помещаявслед за описанием заключенный в фигурные скобки список на-чальных значений, разделенных запятыми. Например программаподсчета символов из главы 1, которая начиналась сMAIN() /* COUNT DIGITS, WHITE SPACE, OTHERS */ ( INT C, I, NWHITE, NOTHER; INT NDIGIT[10]; NWHITE = NOTHER = 0; FOR (I = 0; I < 10; I++) NDIGIT[I] = 0; ... ) Ожет быть переписана в виде INT NWHITE = 0; INT NOTHER = 0; INT NDIGIT[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; MAIN() /* COUNT DIGITS, WHITE SPACE, OTHERS */ ( INT C, I; ... ) Эти инициализации фактически не нужны, так как все присваи-ваемые значения равны нулю, но хороший стиль - сделать ихявными. Если количество начальных значений меньше, чем ука-занный размер массива, то остальные элементы заполняются ну-лями. Перечисление слишком большого числа начальных значенийявляется ошибкой. К сожалению, не предусмотрена возможностьуказания, что некоторое начальное значение повторяется, инельзя инициализировать элемент в середине массива без пере-числения всех предыдущих. Для символьных массивов существует специальный способинициализации; вместо фигурных скобок и запятых можно ис-пользовать строку: CHAR PATTERN[] = "THE"; Это сокращение более длинной, но эквивалентной записи: CHAR PATTERN[] = { 'T', 'H', 'E', '\0' }; Если размер массива любого типа опущен, то компилятор опре-деляет его длину, подсчитывая число начальных значений. Вэтом конкретном случае размер равен четырем (три символаплюс конечное \0).