Подтвердить что ты не робот

Назначить массив массиву

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

int numbers[5] = {1, 2, 3};
int values[5] = {0, 0, 0, 0, 0};
values = numbers; 

Появится следующая ошибка:

Error   1   error C2106: '=' : left operand must be l-value c:\users\abc\documents\visual studio 2012\projects\consoleapplication7\consoleapplication7\main.cpp 9   1   ConsoleApplication7

Почему я не могу так? Что означает ошибка?

4b9b3361

Ответ 1

Массивы имеют множество уродливых действий из-за обратной совместимости с С++ с C. Одно из этих действий состоит в том, что массивы не могут быть назначены. Вместо этого используйте std::array или std::vector.

#include <array>
...
std::array<int,5> numbers = {1,2,3};
std::array<int,5> values = {};
values = numbers;

Если по какой-то причине вы должны использовать массивы, вам придется копировать элементы через цикл или функцию, которая использует цикл, например std::copy

#include <algorithm>
...
int numbers[5] = {1, 2, 3};
int values[5] = {};
std::copy(numbers, numbers + 5, values);

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

int values[5] = {0, 0, 0, 0, 0};
int values[5] = {};

Ответ 2

Вы не можете назначать массивы на С++, это глупо, но это правда. Вы должны копировать элементы массива по одному. Или вы можете использовать встроенную функцию типа memcpy или std::copy.

Или вы можете отказаться от массивов и вместо этого использовать std::vector. Они могут быть назначены.

Ответ 3

Имена массива являются постоянными не изменяемыми значениями l, вы не можете его изменить.

values = numbers; 
// ^
// is array name

Считать сообщение об ошибке компилятора: "error C2106: '=' : left operand must be l-value" Модифицируемое значение l может отображаться в lhs =.

Вы можете назначить имя массива указателю, например:

int* ptr = numbers;

Примечание: имя массива постоянное, но вы можете изменить его содержимое, например. value[i] = number[i] является допустимым выражением для 0 <= i < 5.

Почему я не могу так?

В основном это ограничение назначается языком, внутреннее имя массива используется в качестве базового адреса и путем индексирования с базовым адресом вы можете получить доступ к памяти продолжения памяти, выделенной для массива. Таким образом, в именах массивов C/С++ должно быть указано lhs не l-значение.

Ответ 4

values ​​= numbers; Поскольку числа и значения являются указателями.

int numbers[5] = {1, 2, 3};
int values[5] = {0, 0, 0, 0, 0};
for(int i = 0;i < 5; i ++){
    values[i] = numbers[i];
}

Ответ 5

std::array - хорошая идея, но это также возможно:

struct arr { int values[5]; };

struct arr a{{1, 2, 3}};
struct arr b{{}};

a = b;

В противном случае используйте std::memcpy или std::copy.

Ответ 6

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

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

PS. С философией дизайна для векторов, следующий блок работает хорошо.

vector<int> v = {1, 5, 16, 8};
vector<int> v_2 = {7, 5, 16, 8};
v_2 = v;