Что такое вектор в программировании какой массив
Перейти к содержимому

Что такое вектор в программировании какой массив

  • автор:

Что такое вектор в программировании какой массив

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

Доступ к функциям вектора производится через оператор «.». Вектор – это особый тип данных, шаблон класса. Подробнее о классах и шаблонах см. главу 4 и раздел 5.4.

Для вектора не обязательно сразу указывать его размер, размер вектора можно изменить в любом месте программы при помощи функции resize(), а чтобы узнать размер вектора можно воспользоваться функцией size().

#include using namespace std; vectordouble> x; // создание вектора x.resize(10); // изменение размера вектора x.resize(x.size()+100); // изменение размера вектора double sum=0.0; for(int i=0; i//доступ по индексу >

Полный список функций вектора см. Приложение 5.

Рассмотрим более подробно пример работы с вектором. Обратите внимание, что в этом примере вектор передается в функцию по ссылке, т.к. классы и массивы большого объема нерационально копировать каждый раз при вызове функции, что происходит при передачи по значению. Если функция не должна изменить содержимое контейнера, дополнительно указывается ключевое слово const.

///////////////////////////////////////////////////////////////////////////// // Прикладное программирование // Пример 3.3. Пример работы с контейнером vector // // Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru // Университет ИТМО ///////////////////////////////////////////////////////////////////////////// #include // подключение библиотеки ввода-вывода #include // подключение описания вектора #include // для работы с таймером using namespace std; // подключение стандартного пространства имен для использования библиотек // прототипы функций int min(const vectordouble>& data); void fill_rand(vectordouble>& data, double max, double min); ///////////////////////////////////////////////////////////////////////////// // пример передачи вектора в функцию // функция находит индекс минимального числа в векторе int min(const vectordouble>& data) < int index=0; double min=data[0]; for(int i=1; iif(data[i] > return index; > ///////////////////////////////////////////////////////////////////////////// // Функция заполнения вектора случайными числами // data - вектор для заполнения // max - максимальное число случайного диапазона // min - минимальное число случайного диапазона void fill_rand(vectordouble>& data, double max, double min) < // устанавливает стартовую точку для генерации // случайных чисел по текущему времени srand((unsigned) clock()); for(int i=0; i > ///////////////////////////////////////////////////////////////////////////// void main() < vectordouble> x; // создание вектора // ввод количества элементов в векторе int n; cout"input vector size: "; cin>>n; // 1. заполнение контейнера индексами // заполнение контейнера for(int i=0; i// добавить элемент в конец контейнера x.push_back(i); > // вывод всех элементов контейнера cout<for(int i=0; i; //доступ по индексу > // 2. заполнение контейнера случайными числами от 1 до 100 // очистить контейнер x.clear(); // изменить размер x.resize(20); // заполнить случайными числами fill_rand(x, 1, 100); // вывод всех элементов контейнера cout<for(int i=0; i//доступ по индексу > // вывод минимального числа в контейнере cout<// x[min(x)] аналогично записи int i=min(x); x[i]; > /////////////////////////////////////////////////////////////////////////////// 

При работе с вектором мы сталкиваемся с такими понятиями как размер и емкость. Размер — количество элементов, хранимых в контейнере, можно узнать с помощью функции size(), а изменить с помощью resize(). Операции push_back(), insert(), erase() также изменяют размеры вектора. Когда размеры вектора изменяются, то все его элементы могут быть перемещены в новую область памяти, поэтому хранить указатели на элементы вектора не имеет смысла и может быть опасно. Всегда нужно работать через итераторы (см.раздел 3.5).

С помощью функции empty() можно узнать о наличии элементов в контейнере. Если контейнер действительно пуст, то функция возвращает true.

bool res=x.empty(); // эквивалентно x.size() == 0 

При работе с вектором можно выделить (зарезервировать) некоторую область памяти для потенциального расширения. Использование функции reserve() обеспечить выделение памяти для новых элементов контейнера. При этом вставка новых элементов или изменение размеров с помощью resize() не потребует перераспределения хранимого вектора в памяти. Определить «емкость» вектора можно с помощью функции capaсity().

Массивы

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

Также в примерах предположим, что в начале программы подключено использование пространства имен std.
using namespace std;

  • Описание вектора
  • Количество элементов
  • Добавление элемента в конец вектора
  • Перебор элементов
  • Вставка элемента в произвольное место
  • Удаление элемента
  • Очистка вектора
  • Выделение памяти

При описании вектора, также как и при описании массива, нужно указать тип элементов, из которых он будет состоять. Количество элементов указывать не обязательно, но такая возможность есть.

vector a; // создать пустой вектор vector b(10); // создать вектор из 10 элементов и заполнить его нулями.

Функция size() возвращает количество элементов в векторе.

vector a; . if (a.size() > 20)

Добавление элемента в конец вектора делается с помощью функции push_back(). При этом размер вектора увеличивается на 1.

vector a; . for (int i = 0; i < 10; i++ < cin >> x; a.push_back(x); >

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

Как и в случае с массивом возможен перебор элементов по индексам.

vector a; . for (int i = 0; i ::iterator p; p = a.begin() + 2; // p указывает на 2-й элемент // (при нумерации с 0 — это 3-й от начала) a.insert(p, 5); // получен массив (1 2 5 3 4)

Удаление элемента выполняется с помощью функции erase(). Позиция удаляемого элемента указывается с помощью итератора.

vector a; a.push_back(1); a.push_back(2); a.push_back(3); a.push_back(4); // сформировали массив из чисел (1 2 3 4) vector ::iterator p; p = a.begin() + 1; a.erase(p); // получили массив из чисел (1 3 4)

Функция clear() освобождает память из-под элементов вектора. Размер вектора становится равным нулю.

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

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

#include

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

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

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

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

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

std::vector myVector(10);

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

#include #include // подключаем модель Векторов using namespace std; int main() < vectormyVector(10); // объявляем вектор размером в 10 элементов и инициализируем их нулями // вывод элементов вектора на экран for(int i = 0; i

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

CppStudio.com

0 0 0 0 0 0 0 0 0 0

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

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

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

#include #include // подключаем модель Векторов using namespace std; int main() < vectormyVector1(10); // вывод элементов вектора на экран cout cout << "\nСкопированный массив: "; vectormyVector2(myVector1); // при объявлении второго вектора, копируется - первый for(int i = 0; i < myVector2.size(); i++) < myVector2[i] = i; cout 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 #include using namespace std; int main() < vectorarray1(3); // инициализируем элементы вектора array1 array1[0] = 4; array1[1] = 2; array1[2] = 1; vector array2(3); // инициализируем элементы вектора array2 array2[0] = 4; array2[1] = 2; array2[2] = 1; // сравниваем массивы if (array1 == array2) < cout return 0; >

CppStudio.com

array1 == array2

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

#include #include #include // заголовочный файл итераторов using namespace std; int main() < vectorarray1; // создаем пустой вектор // добавляем в конец вектора 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(cout," ") //итератор потока вывода ); return 0; >

CppStudio.com

4 3 1

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

В чем разница между вектором и массивом

Author24 — интернет-сервис помощи студентам

В чем разница между динамическим массивом и статическим?
ребята, я не понимаю различия. вроде читал литературу. ну вот говорят, что динамический массив.

В чем разница между обычным массивом и контейнером
В чем разница между обычным массивом и контейнером?

В чем разница между массивом строк и List?
А есть ли принципиальная разница между string array1 и List<string> array2 ? И если есть, то в.

Разница между списком и вектором
вот допустим в с++ есть такая тема как списки. препод мой по проги говорит ,что с помощью них можно.

Заблокирован

ЦитатаСообщение от Sylar9 Посмотреть сообщение

Я учу язык С/С++ и хотел у вас спросить в чем разница между вектором и массивом ? кроме тогдо что вектор создается vector m; а массив m[5];

Вектор — это шаблонный класс. А мпссив — это составной тип. То есть вектор имеет методы, с ним связанные, а массив методов не имеет..

Регистрация: 03.11.2016
Сообщений: 138

Например какие методы имеет вектор? Я что то не пойму разницы, методы мы как и массиву так и вектору задаем одинаковые.

Любитель чаепитий
3742 / 1798 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1

ЦитатаСообщение от MilkyWay888 Посмотреть сообщение

Например какие методы имеет вектор?
Тут можно почитать.
http://en.cppreference.com/w/cpp/container/vector

ЦитатаСообщение от Sylar9 Посмотреть сообщение

в чем разница между вектором и массивом ?

Основная разница — размер массива должен быть задан на этапе компиляции и это встроенный тип данных.
А ещё вектор — реализация динамического массива, т.е. он может расширяться. Ну и, соответственно, вектор имеет методы для вставки/удаления этих элементов.

Регистрация: 03.11.2016
Сообщений: 138
Получается что массив находится в стеке скомпилированной программы?
Любитель чаепитий
3742 / 1798 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1

ЦитатаСообщение от MilkyWay888 Посмотреть сообщение

Получается что массив находится в стеке скомпилированной программы?

Не уверен, что это именно так, скорее всего массивы находятся где-то в статической памяти, потому что вот такой код вполне корректен, хотя выделяем мы тут около 100Мб, а стек, как известно, около 2-4Мб.

1 2 3 4 5 6 7 8 9 10
#include int main() { unsigned char arr[104857600]; for( auto& it : arr ) { it = 255; } }

Эксперт C

27699 / 17316 / 3811
Регистрация: 24.12.2010
Сообщений: 38,979

ЦитатаСообщение от GbaLog- Посмотреть сообщение

скорее всего массивы находятся где-то в статической памяти,

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

Любитель чаепитий
3742 / 1798 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1

ЦитатаСообщение от Байт Посмотреть сообщение

Массив, описанный в вашем коде может находиться только в стеке, и нигде больше.

Ну я понимаю, что это не может быть НЕ на стеке. Но странно то, что она не падает! Поэтому я уже и начал думать, что тут что-то не так.
http://rextester.com/WMGG59074 g++
http://rextester.com/IYGCXO86293 clang
А вот vc++ рухнул. http://rextester.com/HRXZ87682 vc++

4817 / 2278 / 287
Регистрация: 01.03.2013
Сообщений: 5,947
Записей в блоге: 28

ЦитатаСообщение от GbaLog- Посмотреть сообщение

Но странно то, что она не падает! Поэтому я уже и начал думать, что тут что-то не так.

std::coutarr[1];

может поменять ваше мнение.

Эксперт C

27699 / 17316 / 3811
Регистрация: 24.12.2010
Сообщений: 38,979

ЦитатаСообщение от GbaLog- Посмотреть сообщение

странно то, что она не падает

ЦитатаСообщение от GbaLog- Посмотреть сообщение

а стек, как известно, около 2-4Мб.

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

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *