Присваивание массивов
Каждый ребенок знает, что массивы и указатели в Си — это не одно и то же. Я обязательно посвящу этому волнующему вопросу один из будущих постов, но сейчас существенно то, что имя массива не может выступать в качестве lvalue. Попросту говоря — массиву нельзя ничего присвоить, поскольку его адрес определяется при компиляции; единственное исключение — первоначальная инициализация, вроде такой:
int a[5] = { 1, 2, 3, 4, 5 };
Если же мы попробуем провернуть такой же фокус в дальнейшем:
15 16 17 | int a[3] = { 1, 2, 3 }; int b[3] = { 3, 2, 1 }; a = b; |
получим по сусалам от компилятора:
$ cc -o0 -g -o test test.c test.c: In function 'main': test.c:17: error: incompatible types in assignment
Казалось бы, типы одинаковые: int[3], но нет, не дают присвоить. Такой вот семантический парадокс.
Но это еще не самое интересное. Самое интересное — массивы таки можно присвоить (читай — скопировать), безо всяких memcpy. Вот глядите:
struct s_tag {int arr[100];} aa, bb; int i; for (i = 0; i < 100; i++) aa.arr[i] = i; bb = aa;
Все прекрасно компилируется и работает, и именно так, как предполагалось: один массив копируется в другой, цикл копирования генерируется компилятором.
Стоит добавить к этому, что при передаче массива в качестве аргумента функции копирование не происходит — передается только адрес. Зато если массив обернуть в структуру и передать ее по значению функции — копируется.
Мораль: массивы — это не совсем указатели и не совсем массивы; во избежание недоразумений необходимо учить матчасть.


(6 голосов, средний: 4,50 из 5)