Ли строковый литерал считается частичным инициализатором и нулевой инициализацией?
В C вы можете частично инициализировать структуру или массив, в результате чего элементы/элементы, которые не упоминаются в инициализаторе, инициализируются нулем. (Раздел C99 6.7.8.19). Например: -
int a[4] = {1, 2};
// a[0] == 1
// a[1] == 2
// a[2] == 0
// a[3] == 0
Вы также можете инициализировать "массив типа символа" строковым литералом (раздел C99 6.7.8.14), а "последовательные символы... инициализировать элементы массива". Например: -
char b[4] = "abc";
// b[0] == 'a'
// b[1] == 'b'
// b[2] == 'c'
// b[3] == '\0'
Все довольно просто. Но что произойдет, если вы явно указали длину массива, но используете литерал, слишком короткий для заполнения массива? Остальные символы ноль-инициализированы или имеют значения undefined?
char c[4] = "a";
// c[0] == 'a'
// c[1] == '\0'
// c[2] == ?
// c[3] == ?
Рассмотрение его как частичного инициализатора имело бы смысл, оно делало бы char c[4] = "a"
вести себя точно так же, как char c[4] = {'a'}
, и это имело бы полезный побочный эффект, позволяя вам с нулевой инициализацией массива всего символа с помощью char d[N] = ""
, но это совсем не ясно для меня, что то, что требует спецификация.
Ответы
Ответ 1
char c[4] = "a";
Все остальные элементы массива будут установлены в 0
. То есть не только c[1]
, но также c[2]
и c[3]
.
Обратите внимание, что это не зависит от продолжительности хранения c
, i. е. даже если c
имеет автоматическую продолжительность хранения, остальные элементы будут установлены на 0
.
Из стандарта C (ударный удар):
(C99, 6.7.8p21) "Если в списке, заключенном в фигурные скобки, меньше инициализаторов, чем в элементе или элементах совокупности, или меньше символов в строковом литерале используется для инициализации массив с известным размером, чем есть элементы в массиве, оставшаяся часть агрегата должна быть инициализирована неявно так же, как объекты со статической продолжительностью хранения."
Ответ 2
Из стандарта C99 (как уже указано ouah):
Если в списке, заключенном в фигурные скобки, меньше инициализаторов, чем элементов или элементов совокупности или меньше символов в строковом литерале, используемом для инициализации массива известных размера, чем есть элементы в массиве, остальная часть совокупности должна быть инициализируется неявно так же, как и объекты, имеющие статическую продолжительность хранения.
и
Если объект с автоматической продолжительностью хранения не инициализируется явно, его значение неопределенно. Если объект с длительностью статического хранения не инициализируется явно, то:
- если он имеет тип указателя, он инициализируется нулевым указателем;
- если он имеет арифметический тип, он инициализируется нулем (положительным или без знака);
- если он является агрегатом, каждый член инициализируется (рекурсивно) в соответствии с этими правилами;
- если это объединение, первый именованный элемент инициализируется (рекурсивно) в соответствии с этими правила.
И char
- это арифметический тип, поэтому оставшиеся элементы массива будут инициализированы до нуля.
Ответ 3
Абсолютно всюду на языке C он следует принципу "все или ничего" для инициализации. Если вы инициализируете агрегат только частично, остальная часть этого агрегата получает нуль-инициализацию.
Можно сказать, что это чрезмерное и менее оптимальное с помощью строк, но это то, как он работает на C.