Объявление массива Char и инициализация в C - PullRequest
20 голосов
/ 12 февраля 2011

Мне было интересно, почему это не разрешено в C:

char myarray[4];

myarray = "abc";

И это разрешено:

char myarray[4] = "abc";

Я знаю, что в первом случае я должен использовать strcpy :

char myarray[4];

strcpy(myarray, "abc");

Но почему не допускается объявление и более поздняя инициализация, а также допускается объявление и одновременная инициализация?Относится ли это к отображению памяти программ на C?

Спасибо!

Ответы [ 5 ]

37 голосов
/ 12 февраля 2011

Это потому, что ваш первый фрагмент кода не выполняет инициализацию , но присваивание :

char myarray[4] = "abc";  // Initialization.

myarray = "abc";          // Assignment.

И массивы не могут быть назначены напрямую в C.

Имя myarray фактически разрешается по адресу его первого элемента (&myarray[0]), который не является lvalue , и поэтому не может быть целью назначения.

4 голосов
/ 12 февраля 2011

Да, это своего рода несоответствие в языке.

"=" в myarray = "abc"; - это присвоение (которое не будет работать, поскольку массив в основном является своего рода указателем на константу), тогда какв char myarray[4] = "abc"; это инициализация массива.Нет возможности для «поздней инициализации».

Вы должны просто запомнить это правило.

1 голос
/ 12 февраля 2011

Это еще один пример C, где один и тот же синтаксис имеет разные значения (в разных местах).Хотя можно утверждать, что синтаксис должен быть разным для этих двух случаев, это так и есть.Идея состоит в том, что не то, что это «не разрешено», а что второе означает что-то другое (это означает «назначение указателя»).

1 голос
/ 12 февраля 2011
myarray = "abc";

... - это присвоение указателя на «abc» указателю myarray.

Это НЕ заполняет буфер myarray «abc».

Если выЕсли вы хотите заполнить буфер myarray вручную, без использования strcpy () вы можете использовать:

myarray[0] = 'a', myarray[1] = 'b', myarray[2] = 'c', myarray[3] = 0;

или

char *ptr = myarray;
*ptr++ = 'a', *ptr++ = 'b', *ptr++ = 'c', *ptr = 0;

Ваш вопрос о разнице между указателем и буфером (массив).Я надеюсь, что теперь вы понимаете, как С обращается к каждому виду.

0 голосов
/ 12 февраля 2011

Я думаю, что это два действительно разных случая.В первом случае память выделяется и инициализируется во время компиляции.Во втором - во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...