it-swarm-ru.tech

Объявление массива Char и инициализация в C

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

char myarray[4];

myarray = "abc";

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

char myarray[4] = "abc";

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

char myarray[4];

strcpy(myarray, "abc");

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

Спасибо!

20
Alexey Pimenov

Это потому, что ваш первый фрагмент кода не выполняет initialization, а assignment:

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

myarray = "abc";          // Assignment.

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

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

36
Frédéric Hamidi

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

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

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

4
Vlad

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

1
davep
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;

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

1
pierre

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

0
Nofate