2013-05-05 10 views
2

Посмотрите на следующий код:Почему спецификатор формата «% s» работает даже для массива символов без ` 0` и распечатывает все его элементы сразу?

#include<stdio.h> 

int main(void) 
{ 
    char name[7]={'E','R','I','C'}; 
    printf("%s",name); 
} 

Он выводит все nameERIC .Why это так не %s должен работать только тогда, когда мы инициализируем массив символов name следующим образом:

char name[7]={'E','R','I','C','\0'}; //With NULL terminator 

Я не принимая во внимание следующее, как это, очевидно, предполагает символьный массив с завершающим нулем:

char name[7]="ERIC" 

ответ

5

В соответствии с the c11 specification

(6.7.9.21) Если есть меньше инициализаторов в распорной корпусе списка, чем есть элементы или члены из совокупности, или меньше символов в строке буквальной, используемые для инициализации массив из известного размера , чем есть элементы в массиве, остальная часть совокупности должна быть , неявно инициализированной так же, как объекты, имеющие статическую продолжительность хранения.

(6.7.9.10) Если объект, который имеет длительность статического или потока хранения не инициализируется в явном виде, а затем:

- если она имеет арифметический тип, то инициализируется (положительный или без знака) равна нулю;

Таким образом, когда вы инициализации массива, как это:

char name[7]={'E','R','I','C'}; 

Это так же, как:

char name[7]={'E','R','I','C', 0, 0, 0}; 

Так name еще нулем.

+0

Почему H2CO3 удалил свой ответ? В любом случае, вы хотите сказать ясным и однозначным словам на основе стандарта, что он безопасен, если размер массива не менее ** на 1 больше, чем предполагаемый количество символов, которые мы хотим инициализировать? –

+0

Кажется, что Тайвань догоняет Венгрию ... LOL ... (H2CO3 - венгерский) –

+0

@ Rüppell'sVulture Я удалил свой ответ, потому что это было неправильно :) Кажется, страшно, что авторитет имеет ** этот эффект ** на голосование - «только потому, что у него есть 69 тыс. репутации, он должен быть прав», и у меня есть три upvotes для неправильного ответа ...>. < – 2013-05-05 08:21:08

2

Из секции C99 7.21.6.1 Пункт 8 %s спецификатор

Если ни один модификатор л Длина не присутствует, аргумент должен быть указателем на начальный элемент массива символьного типа. Символы от массив записаны до (но не включая) завершающий нуль символ. Если задана точность, пишется не более, чем много байт . Если точность не указана или больше, чем размер массива , массив должен содержать нулевой символ.

Поэтому, если у вас есть указатель на char *, который вы печатаете с помощью printf будет печататься до тех пор, пока \0 не найден.

Также

char name[7]={'E','R','I','C'}; является `\0' прекращается в этом случае, так как длина массива составляет 7, но только 4 из местоположений инициализируется, которые приведут в других местах, оставшихся быть инициализирована равными 0.Проверьте ответ johnchen902 на большее.

+0

Только глобальные переменные гарантированно заполняются нулями. –

+0

Я не повторил цитаты @ johnchen902. См. Здесь «... остальная часть совокупности должна быть инициализирована неявно так же, как объекты, имеющие статическую продолжительность хранения». – phoxis