Печать строк и концепция нулевого символа в C - PullRequest
0 голосов
/ 09 января 2019

Читая о печати строк, я натолкнулся на утверждение "printf пишет символ один за другим, пока не встретит нулевой символ. Если нулевой символ отсутствует, printf продолжается после конца до тех пор, пока строка не найдет нулевой символ в памяти ". Поэтому я написал несколько кодов:

Дело 1:

char arr[4] = { 'a', 'b', 'c' } ;

if (arr[3]== '\0')

printf ("%s",arr);

Вывод был abc.

Значит ли это, что компилятор автоматически сохранил '\0' в arr[3]. Потому что, согласно утверждению, printf прекратит работу, только когда встретит '\0'.

Дело 2:

char arr[3] = { 'a', 'b', 'c' } ;

if (arr[3]== '\0')

printf ("%s",arr);

Вывод снова был abc, хотя блока массива arr[3] не существует, так почему же это не ошибка? Кроме того, printf напечатал abc и остановился, что означает, что он должен встретиться с '\0'. Значит ли это, что компилятор создает дополнительный блок массива после arr[2] для хранения '\0'. Если размер массива должен быть увеличен до 4 байтов (1 байт на каждый символ типа символа). Но выполнение оператора printf ("%d",sizeof (arr)); дает мне вывод 3, показывающий, что размер массива не увеличивается, и указывающий, что arr[3] нет. Тогда как условие if (arr[3]== '\0') стало истинным?

Дело 3:

char arr[3] = "abc";

if (arr[3]== '\0')

printf ("%s",arr);

Теперь я получаю сообщение об ошибке, в котором говорится, что "индекс массива 3 находится за концом (который содержит 3 элемента)". Так почему же это не так с case 2 . Означает ли это, что декларации:

char arr[3] = "abc"; и

char arr[3] = { 'a', 'b', 'c' } ; разные.

1 Ответ

0 голосов
/ 09 января 2019

Если размер массива больше, чем число элементов, которые вы явно инициализируете, то остальные элементы будут инициализироваться нулями.

Таким образом, вы можете иметь, например,

char arr[50] = { 'a' };

Первый элемент (arr[0]) будет инициализирован, чтобы содержать 'a', остальные 49 элементов будут равны нулю.

Также обратите внимание, что когда вы определяете массив из трех элементов (как во втором примере в вашем вопросе), а затем используете arr[3]== '\0', вы индексируете за пределами и имеете неопределенное поведение .

Кроме того, содержимое памяти, не входящей в ваш массив, является неопределенным . Вы не можете полагаться на то, что это какое-либо значение.

И, наконец,

char arr[3] = "abc";

и

char arr[3] = { 'a', 'b', 'c' };

фактически одинаковы, оба создают массив из трех элементов с содержанием 'a', 'b' и 'c'.

...