Инициализация массива символов c меньшим строковым литералом
если я напишу:
char arr[8] = "abc";
есть ли какие-либо спецификации над тем, что arr[4]
может быть? Я сделал несколько тестов с
Clang и кажется, что остальные символы в массиве установлены в null.
Кроме того,char arr[8] = "";
нули каждый байт. Не уверен, что это компилятор
удобство, стандартное поведение, чистое совпадение или я ошибся.
void a()
{
char arr[8] = "abc"; /* breakpoint here, line 3 */
strcpy(arr, "1234567");
}
int main()
{
a();
a();
return 0;
}
стенограмма отладчика:
Breakpoint 1, a () at str.c:3 3 char arr[8] = "abc"; (gdb) s Current language: auto; currently minimal 4 strcpy(arr, "1234567"); (gdb) p arr = "abc0000" (gdb) c Continuing. Breakpoint 1, a () at str.c:3 3 char arr[8] = "abc"; (gdb) p arr = "1234567" (gdb) s 4 strcpy(arr, "1234567"); (gdb) p arr = "abc0000"
4 ответов
Это стандартное поведение.
arr[3]
инициализируется как 0, поскольку завершающий 0 является частью строкового литерала.
все остальные элементы также инициализируются до 0 -- ISO / IEC 9899: 1999, 6.7.8, 21:
Если в списке, заключенном в скобки, меньше инициализаторов, чем элементов или членов или меньше символов в строковом литерале, используемом для инициализации массива известных размер, чем есть элементы в массиве остальная часть агрегата должна быть инициализируется неявно так же, как объекты, имеющие статическую длительность хранения.
и char
объекты со статическим хранилищем инициализируются до 0.
char arr[8] = "abc";
полностью эквивалентна
char arr[8] = {'a', 'b', 'c', ''};
ISO C 6.7.8 §21 гласит, что
если в списке, заключенном в скобки, меньше инициализаторов, чем там элементы или члены совокупности символов в строковый литерал, используемый для инициализации массива известного размера являются ли элементы в массиве, остальная часть агрегата должна быть инициализируется неявно так же, как объекты со статическим хранилищем продолжительность.
на простом английском языке это означает, что все значения в конец массива будет равен 0. Таким образом, стандарт гарантирует, что ваш код эквивалентен:
char arr[8] = {'a', 'b', 'c', '', 0, 0, 0, 0};
теперь, конечно, "\0 " также является нулевым значением.
это правило универсально для всех массивов, а не только для строк. Кроме того, то же самое применяется при инициализации структуры, но только явно устанавливая несколько ее членов (6.7.8 §18).
вот почему вы может писать код как
char arr[8] = "";
в этом примере первый элемент массива инициализируется прямо до '\0', а остальные элементы неявно к нулю. Компилятор переводит это в
char arr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
Это стандартное поведение. Каждый элемент массива, который явно не инициализирован, инициализируется значением по умолчанию (''
на char
), если какой-либо префикс массива инициализируется в объявлении. Он также работает для других типов:
int a[10] = {1};
обнуляет a[1]
через a[9]
.
согласно стандарту, все индексы за пределами указанного будут установлены в ноль / null. Дополнительная информация в это так пост