хранение строк в массивах символов в C - PullRequest
2 голосов
/ 24 марта 2010
#include<stdio.h>
int main()
{
  char a[5]="hello";
  puts(a);  //prints hello
}

Почему код компилируется правильно? Нам нужно шесть мест для хранения "hello", верно?

Ответы [ 9 ]

9 голосов
/ 24 марта 2010

Компилятор C позволит вам запустить конец массивов, он не проверяет такого рода.

8 голосов
/ 24 марта 2010

Компилятор C позволяет явно запрашивать нулевой терминатор.

char a[] = "Hello";  /* adds a terminator implicitly */
char a[6] = "Hello"; /* adds a terminator implicitly */
char a[5] = "Hello"; /* skips it */

Любое значение меньше 5 приводит к ошибке.

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

Рекомендуется использовать char a[], чтобы компилятор мог автоматически установить для него правильное значение (включая терминатор).

2 голосов
/ 24 марта 2010

По моему опыту, многие компиляторы позволят вам скомпилировать это. Тем не менее, обычно происходит сбой во время выполнения (поскольку у вас нет нулевого терминатора).

2 голосов
/ 24 марта 2010

a не содержит строки с нулевым символом в конце (дополнительные инициализаторы для массивов фиксированного размера - такие как нулевой терминатор в "hello" - отбрасываются), поэтому поведение, когда указатель на этот массив передается puts не определено.

1 голос
/ 24 марта 2010

C инициализация массива char включает завершающий ноль, только если есть место или если размеры массива не указаны.

0 голосов
/ 05 октября 2015

Это потому, что в C управление памятью осуществляется вручную, в отличие от Java и некоторых других языков .... Выделенные шесть мест не проверяются во время компиляции, но если вы Приступая к регистрации (я имею в виду сохранение), вы получите ошибку времени выполнения, потому что программа сохранила пять мест в памяти (но, как ожидается, будет шесть) для символов, но компилятор не проверял!

0 голосов
/ 24 марта 2010

Компилятор C, который вы используете, не проверяет, соответствует ли строковый литерал массиву char. Вам нужно 6 символов в массиве, чтобы соответствовать литералу "Hello", так как литерал содержит завершающий ноль. Современные компиляторы, такие как Visual C ++ 2010, проверяют эти вещи и выдают ошибку.

0 голосов
/ 24 марта 2010

Вам нужно 6 символов, чтобы сохранить "привет" как завершенную нулем строку. Но массивы символов не ограничены для хранения строки с нулевым символом в конце, вам может понадобиться массив для другой цели, и принудительное использование дополнительного нулевого символа в этих случаях будет бессмысленным.

0 голосов
/ 24 марта 2010

Строка «Привет» хранится в постоянной памяти с 0 в конце. «а» указывает на эту строку, поэтому программа может работать правильно. Но я думаю, что в целом это неопределенное поведение. Необходимо видеть код сборки, сгенерированный компилятором, чтобы увидеть, что именно происходит Если вы хотите получить нежелательный вывод в этой ситуации, попробуйте:

char a[5] = {'h', 'e', 'l', 'l', 'o'}
...