Даже если @JamesMcNellis ответ является допустимым я хотел бы объяснить, что-то об обработке ошибок, а также тот факт, что есть еще один способ сделать то, что вы хотите.
У вас есть три способа доступа конкретного элемента в векторе:
- Использование
[]
оператора
- Использование функции члена
at(...)
- Использование итератора в сочетании с заданным офсетных
В следующих примерах я буду использовать следующий вектор в качестве лабораторной крысы:
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;
Мы получим:
Terminate вызывается после метания экземпляра 'станд :: out_of_range'
, что(): вектор :: _ M_range_check: __n (который 10)> = this-> размер() (который 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(...)
по возможности не только потому, что он более читабельен по сравнению с доступом итератора, а из-за ошибки проверки неверного индекса, который я упомянул выше как для итератора со смещенной комбинацией, так и для оператора []
.
EDIT: Я забыл о std::for_each
от algorithm
заголовка стандартной библиотеки C++. Это еще один способ, который я могу рекомендовать (он использует внутренне итератор). Вы можете узнать больше об этом, например, here.
Все, что случилось с л [4] = -1; Или l.at (4) = -1, если хотите. – 2010-04-12 18:07:27