Сообщение об ошибке, если я попытаюсь скопировать один массив в другой в C

Компилятор выдает мне сообщение об ошибке, если я пытаюсь скопировать один массив в другой с помощью оператора присваивания. Это почему?

Несмотря на то, что это выглядит хорошо для меня, задание,

a = b; //a и b — массивы

является незаконным. Есть ли простой способ скопировать один массив в другой, используя только цикл for?

EDIT Является ли memcpy предпочтительнее цикла в случае небольших массивов?


person Community    schedule 01.02.2017    source источник
comment
Да, вы сами сказали это довольно ясно - используя только цикл for (какой-то).   -  person barak manos    schedule 01.02.2017


Ответы (3)


/* Copying data from array 'a' to array 'b */
   for (i = 0; i < num; i++) {
  arr2[i] = arr1[i];
 }

Массивы не могут быть назначены другому объекту массива или инициализированы из него в C++, потому что это невозможно в C, и они не могут в C по историческим причинам, которые больше не актуальны.

В очень раннем прото-C могла возникнуть некоторая путаница, если присваивание вроде int a[] = {0}; интервал b[] = {0}; а = б; следует скопировать содержимое массива b в массив a или переместить имя a для ссылки на b. Аналогично с инициализацией, должно ли a быть копией b или псевдонимом. Этой двусмысленности не существовало в течение 40 лет: вскоре стало ясно, что если бы это было разрешено, то разумное значение в C (и C++) было бы в том, что оно должно копироваться, но массивы в C никогда не превращались в "правильное" значение. типы.

Нет технических причин, почему это невозможно, и, например, вы можете назначить тип структуры, который имеет массив в качестве члена данных. Стандарт просто не определяет ваш код как правильный C++.

person Shobhit    schedule 01.02.2017

.. Несмотря на то, что мне это нравится,

Подожди, остановись. Массивы не могут быть назначены. Вы не можете использовать переменную типа массива в качестве операнда LHS оператора присваивания.

С моим акцентом, цитируя C11, глава §6.5.16

Оператор присваивания должен иметь модифицируемое lvalue в качестве левого операнда.

и, из §6.3.2.1

.... модифицируемое левое значение — это левое значение, которое не имеет типа массива, не имеет неполного типа, не имеет константного типа и, если оно является структурой или объединением, имеет не иметь ни одного члена (включая, рекурсивно, любой член или элемент всех содержащихся агрегатов или объединений) с типом, уточненным как const.

Вам нужно либо

  • Перебирать отдельные элементы массива и назначать их один за другим (если элементы сами являются массивами, используйте эту теорию рекурсивно)
  • Используйте memcpy().

Тем не менее, "является ли memcpy предпочтительнее цикла в случае небольших массивов?" не имеет однозначного ответа. Вам нужно проверить сгенерированный ассемблерный код, чтобы убедиться. При правильной оптимизации компилятор, скорее всего, выберет лучшее в двух большинстве случаев.

person Sourav Ghosh    schedule 01.02.2017
comment
Привет, спасибо за ваш вклад, memcpy(a,b, sizeof (a)); приемлемо в таком случае? - person ; 01.02.2017
comment
@Rizzo Да, скорее всего - person Sourav Ghosh; 01.02.2017
comment
@Риззо; Это зависит от размера целевого массива. - person haccks; 01.02.2017

В случае массива int не забудьте включить <string.h>:

int * intdup(int const * src, size_t len)
{
   int * p = malloc(len * sizeof(int));
   memcpy(p, src, len * sizeof(int));
   return p;
}

Вы не можете напрямую сделать array1 = array2. Потому что в этом случае вы будете манипулировать адресами массивов, а не их значениями.

person omri_saadon    schedule 01.02.2017
comment
Привет, memcpy(a,b, sizeof (a)); это более простая версия того, что ты делаешь? - person ; 01.02.2017
comment
Вам все еще нужно выделить память для a и умножить sizeof на размер типа данных. - person omri_saadon; 01.02.2017