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

Как изменить определенный элемент вектора STL С++

vector<int> l;
for(int i=1;i<=10;i++){
   l.push_back(i);
}

Теперь, например, как изменить 5th element вектора на -1?

Я попробовал l.assign(4, -1); Он не ведет себя так, как ожидалось. Ни один из других векторных методов не подходит.

Я использовал вектор, поскольку мне нужен случайный доступ в моем коде (используя l.at(i)).

4b9b3361

Ответ 1

at и operator[] возвращают ссылку на индексированный элемент, поэтому вы можете просто использовать:

l.at(4) = -1;

или

l[4] = -1;

Ответ 2

Несмотря на то, что ответ @JamesMcNellis является действительным, я хотел бы объяснить что-то об обработке ошибок, а также о том, что есть другой способ сделать то, что вы хотите.

У вас есть четыре способа доступа к определенному элементу в векторе:

  • Использование оператора []
  • Использование функции-члена at(...)
  • Использование итератора в сочетании с заданным смещением
  • Использование std::for_each из заголовка algorithm стандартной библиотеки С++. Это еще один способ, который я могу рекомендовать (он использует внутренне итератор). Вы можете узнать больше об этом, например здесь.

В следующих примерах я буду использовать следующий вектор в качестве лабораторной крысы и объясню первые три метода:

static const int arr[] = {1, 2, 3, 4};
std::vector<int> v(arr, arr+sizeof(arr)/sizeof(arr[0]));

Это создает вектор, как показано ниже:

1 2 3 4

Сначала рассмотрим способ [] делать вещи. Он работает практически так же, как вы ожидаете при работе с обычным массивом. Вы указываете индекс и возможно, вы получаете доступ к нужному элементу. Я говорю возможно, потому что оператор [] не проверяет, действительно ли вектор имеет много элементов. Это приводит к бесшумному недопустимому доступу к памяти. Пример:

v[10] = 9;

Это может привести или не может привести к мгновенному сбою. Худший случай, конечно, если это не так, и вы действительно получаете то, что кажется действительным. Подобно массивам, это может привести к тратам времени, пытаясь найти причину, по которой, например, 1000 строк кода, вы получите значение 100 вместо 234, которое несколько связано с тем самым местом, где вы извлекаете элемент от вас.

Лучше всего использовать at(...). Это автоматически проверяет поведение out of bounds и разбивает металирование std::out_of_range. Поэтому в случае, когда мы имеем

v.at(10) = 9;

Мы получим:

завершение вызова после вызова экземпляра 'std:: out_of_range'
what(): vector:: _ M_range_check: __n (что равно 10) >= this- > size() (который равен 4)

Третий способ похож на оператор [] в том смысле, что вы можете повредить вещи. Вектор, подобный массиву, представляет собой последовательность блоков непрерывной памяти, содержащих данные того же типа. Это означает, что вы можете использовать свой начальный адрес, назначив его итератору, а затем просто добавьте смещение к этому итератору. Смещение просто означает количество элементов после первого элемента, который вы хотите выполнить:

std::vector<int>::iterator it = v.begin(); // First element of your vector
*(it+0) = 9;  // offest = 0 basically means accessing v.begin()
// Now we have 9 2 3 4 instead of 1 2 3 4
*(it+1) = -1; // offset = 1 means first item of v plus an additional one
// Now we have 9 -1 3 4 instead of 9 2 3 4
// ...

Как вы можете видеть, мы также можем сделать

*(it+10) = 9;

который снова является недопустимым доступом к памяти. Это в основном то же самое, что использование at(0 + offset), но без проверки ошибок вне границ.

Я бы советовал использовать at(...) по возможности не только потому, что он был более читабельным по сравнению с доступом итератора, а из-за ошибки проверки неверного индекса, о котором я упомянул выше, как для итератора со смещенной комбинацией, так и для оператора [].

Ответ 3

Это должно сделать это:

l[4] = -1

Ответ 4

Вы можете использовать оператор

l[4] = -1

Ответ 5

Я предпочитаю

l.at(4)= -1;

а [4] - ваш индекс