Я знаю, что массивы являются l-значениями и не могут быть присвоены, но в этом случае все, что нужно сделать компилятору, - это переназначить указатель. b
должен просто указывать на адрес a
. Почему это невозможно?
Потому что b
не является указателем. Когда вы объявляете и выделяете a
и b
, вы получаете следующее:
+---+
| 1 | a[0]
+---+
| 2 | a[1]
+---+
| 3 | a[2]
+---+
...
+---+
| 4 | b[0]
+---+
| 5 | b[1]
+---+
| 6 | b[2]
+---+
Для каких-либо указателей места не выделяется. Не существует объекта-указателя a
или b
, отдельного от самих элементов массива.
C был получен из более раннего языка под названием B, а в B там был отдельным указатель на первый элемент:
+---+
b: | +-+--+
+---+ |
... |
+----+
|
V
+---+
| | b[0]
+---+
| | b[1]
+---+
...
+---+
| | b[N-1]
+---+
Когда Деннис Ритч ie разрабатывал C, он хотел сохранить семантику массива B (в частности, a[i] == *(a + i)
), но он не хотел хранить этот отдельный указатель где угодно. Поэтому вместо этого он создал следующее правило - если это не операнд операторов sizeof
или унарных &
, или строковый литерал, используемый для инициализации массива символов в объявлении, выражение типа «N-элементный массив T
» будет преобразован («распад») в выражение типа «указатель на T
», и значением выражения будет адрес первого элемента массива, и это значение не является lvalue .
Это имеет несколько практических эффектов, наиболее важным из которых является то, что выражение массива может не быть целью присваивания. Выражения массивов теряют свою "массивность" в большинстве случаев и просто не рассматриваются как другие типы.
Edit
Фактически, это искажает регистр - выражение массива не может быть целью присваивания, потому что выражение массива не является изменяемым l-значением. Правило распада не играет роли. Но утверждение «массивы не обрабатываются как другие типы» по-прежнему остается в силе.
End Edit
В результате вы не можете скопировать содержимое одного массива в другой. используя только оператор =
. Вы должны либо использовать библиотечную функцию, например memcpy
, либо копировать каждый элемент по отдельности.