Инициализация строки в c

Я новичок в программировании на C, поэтому не стесняйтесь поправлять меня, я настаиваю. Мое основное понимание строк в C заключается в том, что когда мы инициализируем строку, нулевой символ автоматически назначается в конце строки, и нулевой символ не может быть прочитан или записан, но используется только для внутреннего использования.

Поэтому, когда я создаю строку размера 4 как char str[3] и назначаю ей слово, скажем, «КРАСНЫЙ», и печатаю его с помощью функции puts или printf("%s",str), я получаю необычный вывод, напечатанный как RED(SMIILEY FACE)

Затем я снова уменьшаю размер строки до char str[2] и назначаю ей RED, а затем компилирую ее, и снова получаю вывод с указанием RE(Smiley face)

Если кто-то может объяснить это мне, я буду благодарен. Размещение кода C ниже

    int main()
{

 char s1[3]="RED";
 char s2[]="RED";
 puts(s1);
 puts(s2);
 printf("%s",s1);
 return 0;
}

person ritam bala    schedule 21.11.2015    source источник
comment
когда мы инициализируем строку, автоматически назначается нулевой символ -- только если вы выделяете для него достаточно места.   -  person David C. Rankin    schedule 21.11.2015


Ответы (2)


Нулевой символ занимает один дополнительный символ (байт). Поэтому вам нужно использовать дополнительный пробел в дополнение к количеству символов в слове, которое вы инициализируете.

 char s1[4]="RED"; //3 for RED and 1 for the null character

С другой стороны

char s2[3]="RED";

нет места для нулевого символа. «КРАСНЫЙ» там есть, но вы столкнетесь с проблемами ввода-вывода при его печати, поскольку в конце нет нулевого символа. Ваши данные хранятся нормально, но они не могут быть правильно распознаны printf, так как нет нулевого символа.

 char s2[]="RED";

Это будет работать, поскольку автоматически назначается память из 4 (байтов), включая пространство для завершающего нулевого символа.

person ma08    schedule 21.11.2015

char s1[3] = "RED";

Является действительным утверждением. Он копирует 3 символа из константного строкового литерала "RED" (длиной 4 символа) в массив символов s1. В s1 нет окончания '\0', потому что для него нет места.

Обратите внимание на копию, потому что s1 является изменяемым, а "RED" — нет. Это отличает утверждение от, например, const char *s1 = "RED";, где строка не копируется.

Результат как puts(s1), так и printf("%s", s1) не определен. В s1 нет окончания '\0'. Обработка его как строки с единицей может привести к произвольному поведению.

char s2[] = "RED";

Здесь sizeof(s2) == 4, поскольку "RED" состоит из четырех символов, вам нужно учитывать '\0' в конце при вычислении пробела.

person dhke    schedule 21.11.2015
comment
char s3[2] = "RED"; неправильно сформирован - person M.M; 21.11.2015
comment
И просто придирка по поводу если вы определяете, на самом деле должно быть, если вы объявляете, «определять» — это совсем другое, но я знаю, что вы имели в виду, поэтому слово придираться. - person David C. Rankin; 21.11.2015
comment
@m-m: Можете ли вы указать это в стандарте? Похоже, присваивание минус 1 определено для C++ как исключение, но я не могу ради него найти случай, когда у вас действительно слишком много элементов. - person dhke; 21.11.2015
comment
@DavidC.Rankin Спасибо. Тривиально решается удалением последнего примера до тех пор, пока не будет выяснено, что такое требуемое поведение. C99 имеет пример, но только для пропуска завершающего нуля. - person dhke; 21.11.2015