Другое последствие динамического характера векторов станет яснее, когда мы узнаем больше об их использовании. Но есть одно последствие, на которое стоит обратить внимание уже сейчас: по причинам, изложенным в разделе 5.4.3, нельзя использовать серийный оператор for, если тело цикла добавляет элементы в вектор.
Тело серийного оператора
for не должно изменять размер перебираемой последовательности.
Упражнение 3.14. Напишите программу, читающую последовательность целых чисел из потока cin и сохраняющую их в векторе.
Упражнение 3.15. Повторите предыдущую программу, но на сей раз читайте строки.
3.3.3. Другие операции с векторами
Кроме функции push_back(), шаблон vector предоставляет еще несколько операций, большинство из которых подобно соответствующим операциям класса string. Наиболее важные из них приведены в табл. 3.5.
Таблица 3.5. Операции с векторами
v.empty()
|
Возвращает значение true, если вектор v пуст. В противном случае возвращает значение false |
v.size()
|
Возвращает количество элементов вектора v |
v.push_back(t)
|
Добавляет элемент со значением t в конец вектора v |
v[n]
|
Возвращает ссылку на элемент в позиции n вектора v |
v1 = v2
|
Заменяет элементы вектора v1 копией элементов вектора v2 |
v1 = {a,b,с ... }
|
Заменяет элементы вектора v1 копией элементов из разделяемого запятыми списка |
v1 == v2 v1 != v2
|
Векторы v1 и v2 равны, если они содержат одинаковые элементы в тех же позициях |
<, <=, >, >= |
Имеют обычное значение и полагаются на алфавитный порядок |
Доступ к элементам вектора осуществляется таким же способом, как и к символам строки: по их позиции в векторе. Например, для обработки все элементов вектора можно использовать серийный оператор for (раздел 3.2.3).
vector<int> v{1,2,3,4,5,6,7,8,9};
for (auto &i : v) // для каждого элемента вектора v
// (обратите внимание: i - ссылка)
i *= i; // квадрат значения элемента
for (auto i : v) // для каждого элемента вектора v
cout << i << " "; // вывод элемента
cout << endl;
В первом цикле управляющая переменная i определяется как ссылка, чтобы использовать ее для присвоения новых значений элементам вектора v. Используя спецификатор auto, позволим вывести ее тип автоматически. Этот цикл использует новую форму составного оператора присвоения (раздел 1.4.1). Как известно, оператор += добавляет правый операнд к левому и сохраняет результат в левом операнде. Оператор *= ведет себя точно так же, но перемножает левый и правый операнды, сохраняя результат в левом операнде. Второй серийный оператор for отображает каждый элемент.
Функции-члены empty() и size() вектора ведут себя так же, как и соответствующие функции класса string (раздел 3.2.2): функция empty() возвращает логическое значение, указывающее, содержит ли вектор какие-нибудь элементы, а функция size() возвращает их количество. Функция-член size() возвращает значение типа size_type, определенное соответствующим типом шаблона vector.