Дилемма инициализации массива Char - PullRequest
3 голосов
/ 02 августа 2011

Рассмотрим следующий код:

// hacky, since "123" is 4 chars long (including terminating 0)
char symbols[3] = "123";

// clean, but lot of typing
char symbols[3] = {'1', '2', '3'};

Итак, твист на самом деле описан в комментарии к коду, есть ли способ инициализировать char[] строковым литералом, не заканчивая нулем?

Обновление : кажется, что IntelliSense действительно не прав, это поведение явно определено в стандарте C.

Ответы [ 3 ]

13 голосов
/ 02 августа 2011

Это

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 можно найти здесь .

4 голосов
/ 02 августа 2011

Если ваш массив длиной всего 3 символа, первая строка кода идентична второй.'\0' в конце строки просто не будет сохранен.В этом нет ничего «грязного» или «неправильного».

0 голосов
/ 02 августа 2011

1) Упоминаемые вами проблемы не являются проблемами .2) Que: Есть ли способ инициализировать char [] строковым литералом, не заканчивая нулем?- вы уже делаете это.

...