Введение в вектора в C++

Если до сих пор вы пользовались «чистыми» массивами в языке С++, вы многое потеряли. Под «чистыми» массивами я подразумеваю обычное использование массивов в С++, без специальных функций и методов. Прочитав эту статью, вы узнаете как можно работать с массивами на более высоком уровне, вы сможете обрабатывать массивы (объявление, инициализация, поиск, сортировка и многие другие операции) буквально несколькими строчками.
Итак, что же такое «Вектор» в языке С++? Простыми словами вектор можно описать как абстрактную модель, которая имитирует динамический массив. Пока не стоит углубляться в это определение, сейчас мы приступим к практике и вам все станет понятно.
Если мы хотим использовать векторы в своей программе, необходимо подключить заголовочный файл <vector>:

#include <vector>

Вектор можно объявить следующим образом:

std::vector<int> myVector; // мы создали пустой вектор типа int
myVector.reserve(10);      // тут мы зарезервировали память под 10 элементов типа int

Как видно из примера, вектора относятся к пространству имен std. По сути, эти две записи эквивалентны такой записи:

int myVector[10]; // обычное объявление массива

На первый взгляд, объявление вектора оказалось намного более громоздкое. Однако вектора скрывают очень мощный функционал, чего нельзя сказать об обычных массивах С++. Кроме того, вектор можно объявить и в одной строке, вот так:

std::vector<int> myVector(10);

Эта запись эквивалентна двум предыдущим, то есть здесь мы объявили вектор с начальным размером в 10 элементов типа int. Но кроме этого, такой способ объявления вектора не просто выделяет память, но и еще инициализирует все элементы вектора нулями. Вот пример:

#include <iostream>
#include <vector> // подключаем модель Векторов
using namespace std;
int main()
{
    vector<int> myVector(10);   // объявляем вектор размером в 10 элементов и инициализируем их нулями
    // вывод элементов вектора на экран
    for(int i = 0; i < myVector.size(); i++)
        cout << myVector[i] << ' ';
    return 0;
}

Обратите внимание на то, что размер вектора определяется методом size(), это очень удобно, если мы не знаем размер массива. Вывод:

CppStudio.com
0 0 0 0 0 0 0 0 0 0

Если объявить вектор таким образом:

vector<int> myVector;   // объявляем пустой вектор
myVector.reserve(10);   // выделяем память под 10 элементов

то результат работы программы будет другим, в потоке вывода ничего не появится, так как нет начальной инициализации элементов вектора, а значит этот способ объявления вектора выполнится быстрее. Именно в этом и заключается разница этих способов объявления векторов.
Несколькими абзацами выше, я упомянул о начальном размере вектора. Почему же начальный размер? Потому, что, если размера вектора будет не хватать, вектор автоматически будет увеличиваться, при добавлении новых элементов, пересчитывая свой размер. Это очень удобно, так как за частую мы не можем предугадать размер массива, который нам нужен для работы программы. Более подробно мы рассмотрим этот пример немного позже.
Смотрите как легко можно скопировать вектор:

#include <iostream>
#include <vector> // подключаем модель Векторов
using namespace std;
int main()
{
    vector<int> myVector1(10);
    // вывод элементов вектора на экран
    cout << "Входной массив: ";
    for(int i = 0; i < myVector1.size(); i++) {
        myVector1[i] = i;
        cout << myVector1[i] << ' ';
    }
    cout << "\nСкопированный массив: ";
    vector<int> myVector2(myVector1);	// при объявлении второго вектора, копируется - первый
    for(int i = 0; i < myVector2.size(); i++) {
        myVector2[i] = i;
        cout << myVector2[i] << ' ';
    }
    return 0;
}

Вывод:

CppStudio.com
Входной массив: 0 1 2 3 4 5 6 7 8 9 
Скопированный массив: 0 1 2 3 4 5 6 7 8 9

Из результат работы программы хорошо видно ,что в строке 14, была создана копия вектора myVector1.  Рассмотрим программу, в которой сравниваются два массива:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> array1(3);
    // инициализируем элементы вектора array1
    array1[0] = 4;
    array1[1] = 2;
    array1[2] = 1;
    vector<int> array2(3);
    // инициализируем элементы вектора array2
    array2[0] = 4;
    array2[1] = 2;
    array2[2] = 1;
    // сравниваем массивы
    if (array1 == array2) {
        cout << "array1 == array2" << endl;
    }
    return 0;
}

Результат:

CppStudio.com
array1 == array2

Итак, массивы мы инициализировали обыкновенным для нас способом, строки 8-10 и 13-15. Самое удивительное то, что операция сравнивания векторов выполняется в одну строку, строка 17. Попробуйте сделать то же самое с обычными массивами в С++, уверен, что у вас ничего не получится.
До этого, во всех примерах в этой статье я выводил элементы массива используя цикл, с векторами можно обойтись и без него. Смотрим как именно это делается.

#include <iostream>
#include <vector>
#include <iterator> // заголовочный файл итераторов
using namespace std;

int main()
{
    vector<int> array1; // создаем пустой вектор
    // добавляем в конец вектора array1 элементы 4, 3, 1
    array1.insert(array1.end(), 4);
    array1.insert(array1.end(), 3);
    array1.insert(array1.end(), 1);
    // вывод на экран элементов вектора
    copy( array1.begin(),   // итератор начала массива
          array1.end(),     // итератор конца массива
          ostream_iterator<int>(cout," ")   //итератор потока вывода
        );
    return 0;
}

Результат:

CppStudio.com
4 3 1

Итак, начнем по порядку. В строке 3 я добавил новый заголовочный файл, для использования итераторов. Так как в строке 8 мы создали пустой вектор, то конец вектора — это его начало, ведь в векторе нет никаких элементов. Так что, когда мы добавляем новые элементы в массив, мы должны использовать итератор array1.end(), а не итератор array1.begin(). Иначе порядок элементов в массиве станет противоположным. В строках 10-12 мы используем метод insert(), который позволяет вставить элемент в массив. Ну и самое главное, вывод элементов массива выполняется не через цикл а через операцию copy(). В первых двух параметрах мы указали итераторы начала и конца вектора. В третьем параметре указан поток вывода coutostream_iterator<int>(cout," "). Как по мне, такой способ организации вывода на экран намного красивее выглядит, хотя, возможно сразу и не понятен для новичка. Но вы просто постарайтесь его принять как должное и запомнить.

Автор: Marienko L.
Дата: 15.01.2014
Поделиться:

Комментарии

  1. TonyVCLCSA .

    Не, ну как так? Учишь теорию, разбираешь алгоритмы, решаешь задачки, везде массивы, а потом оказывается, что массивы это грубо и некультурно и нужно пользоваться векторами)

  2. Muhammadjon

    У меня скоро экзамен на программу С++  от этого зависит моё  БУДУЩИЕ большой RESPECT  СОЗДАТЕЛЮ САЙТА

  3. Muhammadjon

    Пожалуйста напишите больше уроков на программу С++ 

  4. Muhammadjon

    Ваш постоянный посетитель с уважением Muhammadjon

  5. Muhammadjon

    Занимаюсь программированием на С++ мне всего 12 лет пожалуйста ставьте больше уроков и  как добавить библиотеку в С++ например SFML

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.