int array[3] = {1,2,3}
выделяет массив, который может содержать не более 3 целые числа, и вы можете получить доступ к любому из них, используя следующие способы:
array[0]
array[1]
array[2]
Здесь:
char array[3] = "123"
"123"
состоит из 4 байт. Символы в строковом литерале заканчиваются NUL-терминатором. Но вы выделяете 3 байта и можете удерживать 2 символа (+1 для NUL-терминатора). Итак, когда вы инициализируете массив с ним, '\0'
не записывается, так как нет места.
При печати с использованием этого %s
в printf
, он не вызывает Undefined behavior как %s
печатает все, пока NUL-терминатор. Таким образом, printf
продолжает считывать значения из недопустимых мест памяти до '\0'
. Все может случиться, когда вы это сделаете. Вы можете увидеть случайный вывод мусора, сбои, ошибки сегментации и т. Д. В принципе, вы никогда не должны полагаться на это поведение, даже если оно, казалось, «работало», как ожидалось.
но не массив начинается с 0
Да
так char array[3]
достаточно, так как он на самом деле 4 пространство
Неправильно. Допустимые показатели для char array[3]
являются
array[0]
array[1]
array[2]
доступа array[3]
неправильно и это вызывает Undefined Behavior.
Исправлена проблема с использованием
char array[4] = "123";
или лучше:
char array[] = "123";
Пустые скобки говорят компилятору, чтобы определить размер массива.
Доступ к 'array [3]' конечно это неопределенное поведение, но инициализация 'array' сама определена так, что инициализация' array' выше эквивалентна 'char array [] = {'1', '2', '3'}; '. Номер для нулевого терминатора не является обязательным. С другой стороны, 'char array [3] =" 1234 ";' undefined, поскольку "ни один инициализатор не пытается указать значение для объекта, не содержащегося в инициализированном объекте" (C11 draft N1570 6.7.9p2), что означает что 'array' слишком мал, чтобы содержать 4 элемента' {'1', '2', '3', '4'} '. 6.7.9p32 из N1570 выражает предполагаемое поведение. –
@ ChronoKitsune, я этого не знал! Итак, '' \ 0'' не поставляется? –
Если для этого достаточно места, нулевой ограничитель включен, но он не нужен. Технически любые лишние элементы в любом случае инициализируются до 0, поэтому даже если нулевой ограничитель из строкового литерала не был добавлен, массив все равно будет прекращен, если длина массива будет больше длины строкового литерала. –