STL Vector Первое знакомство с вектором

Этот материал не относится к старым досовским компиляторам. В Borland C++ 3.1 нет понятия STL. Я использовал Visual Studio 2005, который замечательно работает в Windows 7

  • Векторы являются частью STL и относятся к последовательным контейнерам.
  • Последовательные контейнеры — это упорядоченные коллекции, в которых каждый элемент занимает определенную позицию.
    Согласно стандарту C++, любой контейнер должен содержать методы begin(), end(), size(), max_size(), empty(), и swap().

Вектор (vector) почти то же самое, что массив, к его элементам можно обращаться также как к элементам массива. Но у вектора есть некоторые преимущества. Не нужно специально следить за размером, так как вектор свой размер знает. Чтобы поменять размер достаточно удалить или добавить элементы во время выполнения

Чтобы использовать вектор в программе, нужно подключить директиву vector и указать используемое пространство имен std

Все Это легче понять тем, кто знаком с массивами

Смотрим на схожесть обработки вектора и массивов

Думаю кто уже изучал основы, тот сходу поймет что здесь к чему.

===================
Основные методы Вектора
push_back(element) — добавить элемент в конец vector-а
pop_back(element) — удалить последний элемент vector-а
insert(***) — три варианта(перезагрузки метода) вставки в какую либо область в векторе, первый параметр позиция вставки заданная итераторам, остальные указывают на контейнер, или количество и контейнер, или пару итераторов указывающих от какой до какой позиции из другого контейнера взять данные.
erase(iterator или iterator от, и до) — удаляет элемент или последовательность элементов из vector-а
begin() — возвращает итератор, указывающий на начало коллекции.
end() — возвращает итератор, указывающий на конец коллекции. При этом он указывает не самый последний элемент, а на воображаемый элемент за последним.
at(index) — метод доступа, к элементам коллекции, в отличии от оператора [], проверяет выход из-за границ коллекции, и в случаи чего генерит исключение.
clear() — удаляет все элементы коллекции, при этом если в нем содержаться объекты классов вызывает их деструкторы. А если же указатели на объекты, то у Вас будет утечка памяти(memory leaks=)), так delete за Вас никто не вызовет.
===================

Начал я свое знакомство с векторами с первого и второго методов push_back и pop_back.
Привожу код программы с моей небольшой ошибкой

Когда я писал такой код, то не совсем понимал метод push_back, поэтому на экран получил нули и стал искать в чем дело. Возможно кто-то из читателей мог как и я невнимательно прочитать что это за метод такой push_back, потоэму повторюсь — добавляет элементы в конец списка. Другими словами эта моя программа увеличила размер массива путем добавления новых к нему элементов и чтобы увидеть весь массив, нужно этот массив выводить с правильным размером

Код С++ вывод вектора на экран

Использовать метод size всяко удобнее чем указывать размер цифрами.

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

================
Может возникнуть необходимость вывода вектора на экран с помощью итераторов, примером ниже показано как это выглядит в программе

По самому коду почти то же самое, что и вывод без итератора. После написания такого примера мне стало интересно как инициализировать вектор значениями сразу при объявлении. Я использую не самую новую версию Visual Studio, поэтому у тех у кого новее возможно это можно сделать некоторыми способами, которые в моей версии компилятора недоступны.

Код С++ инициализация вектора значениями с помощью имитирования массива

вообще в некоторых версиях компиляторов, которые новее Visual Studio 2005 поддерживается стандарт, благодаря которому можно использовать инициализацию векторов также как и массивов

Чтобы такая инициализация векторов работала, возможно в компиляторе нужно поставить какой-то флаг в настройках. Где этот флаг я не знаю, так что не стоит спрашивать. Мне придется обходится дополнительным массивом.

Я не думаю, что мне стоит расписывать каждый метод. Мне (может и ошибочно) кажется, что тот кто представляет то такое массив, тот посмотрев на то, что тут уже описано легко поймет что к чему

Кроме этого, имеет смысл рассказать о некоторых других особенностях векторов. Одна из таких особенностей, это то, что вектор умеет расширять объем памяти при добавлении элементов, но никогда самостоятельно не уничтожает её. Вместо того, чтоб уничтожить выделенную память, он оставляет эту память в резерве. Если бы вектор мыслил, то его мысли звучали бы так: «А вдруг потом пригодится, буду я ему (своему папе) снова выделять, то что уже выделял, обойдется». Т.е. если насильно не заставить его очистить память, то сколько максимальной памяти было выделено, столько и остается выделено. Связано это с тем, что выделение памяти операция требующая некоторых затрат времени, следовательно сильно снижают эффективность программы. Следует понимать и различать два понятия: Емкость и Размер вектора. Под емкостью вектора понимается то, сколько элементов в вектор можно положить без дополнительного выделения памяти, а под размером понимается то, сколько элементов хранит в себе вектор. Для того, чтоб узнать размер вектора используется метод вектора size, а для того, чтобы узнать емкость вектора используется метод capacity. Стоит обратить внимание на то, что метод capacity отображает общее количество элементов, а не то, сколько элементов можно добавить дополнительно без дополнительных выделений памяти

Для тех кто работал со строками, скорее всего будет понятнее что обозначает то, что я только что написал. Обычно под строку выделяется определенное количество памяти и при выводе строки, строка выводится до признака окончания, но за признаком окончания строки в лежит мусор. Вот вся строка, включая мусорный участок — это как емкость вектора.

Резервировать память в векторе можно самостоятельно, для этого используется метод reserve.
Небольшой итог к вышесказанному

При работе с векторами нужно уметь работать и с памятью и с количеством элементов вектора.

  • Для работы с элементами:  size и resize
  • Для работы с памятью:    capacity и reserve

Для того, чтоб освободить зарезервированную память в векторе используют трюк с обменом Swap Trick

Кое что, чего я не договорил можно узнать на блоге Алены

  • для предотвращения лишних операций перераспределения памяти рекомендуется использовать reserve

К особенностям работы с векторами, можно добавить и то, что скорость работы векторов уступает скорости работе массивов и то, что емкость вектора больше чем объем занимаемой памяти обычного массива. Нетрудно понять, что это легко отнести к категории недостатков. Есть у вектора еще недостаток reallocate (пока не сталкивался, но поверю на слово тому кто это написал)

Еще есть такой способ вывода вектора С++ на экран

Здесь происходит следующее. cout представляет собой объект, т.е. обычную переменную определенного типа. Следовательно в эту переменную можно запихать данные. Чтобы запихать данные, нужно, чтобы тип данных совпадал. cout является объектом класса ostream, вот и видим, что ostream_iterator, т.е. итератор для класса ostream, содержащий int значения (значения типа int хранит вектор, следовательно копировать надо int). Так и происходит копирование значений в cout, после чего мы видим результат на экране.

Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

Добавить комментарий

Ваш e-mail не будет опубликован.

Поиск

 
     
Яндекс.Метрика

НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Мы должны убедиться, что сайтом пользуется не робот!!! Для этого разденьтесь догола и включите wеb-камеру.

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

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок