Это
char symbols[3] = "123";
является действительным утверждением.
Согласно спецификации ANSI C 1988 года:
Массив символьного типа может быть инициализирован символьной строкой
буквально, необязательно заключенный в фигурные скобки. Последовательные персонажи
символьная строка (включая завершающий нулевой символ, если
есть место или, если массив имеет неизвестный размер) инициализировать
члены массива.
Следовательно, то, что вы делаете, технически прекрасно.
Обратите внимание, что символьные массивы являются исключением из установленных ограничений для инициализаторов:
В списке инициализаторов не должно быть больше инициализаторов, чем
являются объектами для инициализации.
Тем не менее, техническая правильность фрагмента кода является лишь малой частью «качества» этого кода. Строка char symbols[3] = "123";
немедленно поразит ветерана-программиста как подозрительного, потому что, по-видимому, она является действительной инициализацией строки и может впоследствии использоваться как таковая, что приводит к неожиданным ошибкам и некоторой смерти.
Если вы хотите пойти по этому пути, вы должны быть уверены, что это то, что вы действительно хотите. Сохранение этого лишнего байта не стоит тех проблем, с которыми вы можете столкнуться. Символ NULL, во всяком случае, позволяет вам писать более гибкий и гибкий код, поскольку он обеспечивает однозначный (в большинстве случаев) способ завершения массива.
(проект спецификации доступен здесь .)
Чтобы принять комментарий Руди в другом месте на этой странице, 32-й пример спецификации проекта C99 в §6.7.8 (стр. 130) гласит, что строки
char s[] = "abc", t[3] = "abc";
идентичны
char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
Из которого вы можете вывести ответ, который ищете.
Черновик спецификации C99 можно найти здесь .