Ответ 1
Говоря о том, что массив является типом данных, что это означает?
Тип данных представляет собой набор данных со значениями, имеющими предопределенные характеристики. Примеры типов данных: целое число, число единиц с плавающей запятой, символ, строка и указатель
Массив - это группа мест памяти, связанная с тем, что все они имеют одно и то же имя и один и тот же тип.
Если вам интересно, почему массив не модифицируется, лучшее объяснение, которое я когда-либо читал;
C не полностью сформировался из ума Денниса Ритчи; он был получен из более раннего языка, известного как B (который был получен из BCPL). 1 B был "беспричинным" языком; у него не было разных типов для целых чисел, поплавков, текста, записей и т.д. Вместо этого все было просто слово с фиксированной длиной или "ячейка" (по существу целое число без знака). Память рассматривалась как линейный массив ячеек. Когда вы выделили массив в B, например
auto V[10];
компилятор выделил 11 ячеек; 10 смежных ячеек для самого массива, плюс ячейка, связанная с V, содержащая местоположение первой ячейки:
+----+
V: | | -----+
+----+ |
... |
+----+ |
| | <----+
+----+
| |
+----+
| |
+----+
| |
+----+
...
Когда Ричи добавлял типы struct
к C, он понял, что это соглашение вызывает у него некоторые проблемы. Например, он хотел создать тип структуры для представления записи в таблице файлов или каталогов:
struct {
int inumber;
char name[14];
};
Он хотел, чтобы структура не просто описала запись абстрактным образом, но также представляла биты в записи фактической таблицы файлов, в которой не было лишней ячейки или слова для хранения местоположения первого элемента в массив. Поэтому он избавился от него - вместо того, чтобы отложить отдельное место для хранения адреса первого элемента, он написал C, чтобы адрес первого элемента вычислялся при вычислении выражения массива.
Вот почему вы не можете сделать что-то вроде
int a[N], b[N];
a = b;
потому что как a
, так и b
оценивают значения указателя в этом контексте; это эквивалентно написанию 3 = 4
. В памяти нет ничего, что фактически хранит адрес первого элемента в массиве; компилятор просто вычисляет его во время фазы перевода.
<Суб > 1. Это все взято из статьи Разработка языка C
Более подробно вы можете прочитать этот ответ.
EDIT: Для большей ясности; Разница между изменяемыми значениями l, немодифицируемыми значениями l и r-значением (короче);
Разница между этими выражениями такова:
- Модифицируемое l-значение адресуется (может быть операндом унарного &) и присваиваемым (может быть левым операндом =).
- Немодифицируемое значение l является адресным, но не назначается.
- Значение r не адресуется и не присваивается.