Въведение
Масивът е поредица от едни и същи типове обекти в последователни места на паметта. Масивът не може да увеличи дължината на рудата. Векторът е като масив, но дължината му може да бъде увеличена или намалена. Следователно един вектор има много повече операции от масив.
C ++ има много библиотеки, всички от които формират стандартната библиотека C ++. Една от тези библиотеки е библиотеката на контейнери. Контейнерът е колекция от обекти и върху него могат да се извършват определени операции. Контейнерите на C ++ могат да бъдат групирани в два комплекта: контейнери за последователност и асоциативни контейнери. Контейнерите за последователност са вектор, масив (не е същият масив, обсъден по-рано), deque, forward_list и list. Това са различни колекции (подобни на масиви структури от данни) и всяка предлага различни компромиси.
Всеки програмист трябва да знае как да реши дали да използва вектор, масив, deque, forward_list или списък. Когато програмист се нуждае от структура, която изисква повече операции от тези, свързани с обикновен масив, обикновеният масив не трябва да се използва.
Ако задачата включва чести вмъквания и изтривания в средата на последователността, тогава трябва да се използва списък или forward_list. Ако задачата включва чести вмъквания и изтривания в началото или края на последователност, тогава трябва да се използва deque. Трябва да се използва вектор, когато този вид операции не се изискват.
Тази статия ви показва как да използвате вектора C ++. За да разберете тази статия, ще ви трябват известни познания за указатели, препратки и масиви на C ++.
Клас и обекти
Класът е набор от променливи и функции, които работят заедно, където променливите нямат зададени стойности. Когато стойностите се присвояват на променливите, клас се превръща в обект. Различните стойности, дадени на един и същи клас, водят до различни обекти; тоест различните обекти могат да бъдат от един клас, но да имат различни стойности. Създаването на обект от клас е известно и като създаване на екземпляр на обекта.
Терминът вектор описва клас. Обект, създаден от вектор, има име, което се избира от програмиста.
Функция, която принадлежи на клас, е необходима за създаване на екземпляр на обект от класа. В C ++ тази функция има същото име като името на класа. Различните обекти, създадени (инстанцирани) от класа, имат различни имена, дадени на всеки от тях от програмиста.
Създаването на обект от клас означава конструиране на обекта; това също означава екземпляр на обекта.
Класът вектор
Класът вектор вече е дефиниран и е в библиотеката. За да използва векторния клас, програмистът трябва да включи векторния заглавие във файла със следната директива за предварителна обработка:
#includeСлед като заглавката бъде включена, всички векторни функции (членове на данни и функции на членове) стават достъпни. За да се използва обектът count за извеждане на данни към терминала (конзолата), заглавката на обекта също трябва да бъде включена. За да напишете програма с вектора, като минимум, трябва да бъдат включени следните заглавия:
#include#include
Инсталиране на вектор
int foo [10];По-горе е декларацията на масив с името „foo“ и броя на елементите „10.”Това е масив от цели числа. Декларирането на вектор е подобно. За вектор броят на елементите не е задължителен, тъй като дължината на вектора може да се увеличава или намалява.
На този етап в програмата векторният клас вече е дефиниран в библиотеката и заглавката е включена. Векторът може да бъде създаден по следния начин:
std :: векторТук векторът е на специалната конструкторска функция. Типът данни, които ще съхранява векторът, е „int“ в ъглови скоби. Терминът „vtr“ е името, избрано от програмиста за вектора. И накрая, „8“, в скоби, е предварителният брой цели числа, които ще има векторът.
Терминът „std“ означава стандартно пространство от имена. В този контекст този термин трябва да бъде последван от двойно двоеточие. Всеки може да напише своя собствена библиотека с векторни класове и да я използва. C ++ обаче вече има стандартна библиотека със стандартни имена, включително „вектор.”За да използвате стандартно име, стандартното име трябва да бъде предшествано от std :: . За да избегнете въвеждането на std :: всеки път в програмата за стандартно име, програмният файл може да стартира по следния начин:
#include#include
използване на пространство от имена std;
Претоварване на функция
Когато два или повече различни подписи на функции имат едно и също име, се казва, че това име е претоварено. Когато се извика една функция, броят и видът аргументи определят коя функция се изпълнява.
Изграждане на вектор
Конструирането на вектор означава създаване на екземпляр (създаване) на векторен обект. Функцията конструктор е претоварена, както следва:
вектор
Това създава вектор с дължина нула и напишете „T.”Следващият израз създава вектор с нулева дължина от типа“ float ”с името“ vtr: ”
векторвектор
Това създава вектор с n елемента от тип „T.”Оператор за този вектор с четири плаващи елемента е както следва:
векторвектор
Това създава вектор от n елемента, инициализирани към стойността t. Следващият израз създава вектор от 5 елемента, където всеки елемент има стойността 3.4:
векторКонструиране с инициализация
Векторът може да бъде конструиран (създаден) и инициализиран едновременно по един от следните два начина:
векторИли
векторИмайте предвид, че няма скоби точно след името на обекта. Скобите, използвани непосредствено след името на обекта, трябва да имат списък за инициализация, както следва:
векторВекторът може да бъде конструиран и инициализиран по-късно със списъка на инициализатора. В този случай скобите няма да бъдат използвани:
векторvtr = 1.12.2, 3.3, 4.4;
вектор
Това е конструктор за копиране. Той създава вектор V2 като копие на вектора V1. Следният код илюстрира това:
векторвектор
Присвояване на вектор по време на строителството
По време на конструирането може да се създаде празен вектор, докато му се присвоява друг, както следва:
векторвектор
Второто твърдение е еквивалентно на:
векторconst Vector
Const вектор е вектор, чиито елементи не могат да бъдат променяни. Стойностите в този вектор са само за четене. Когато е създаден, векторът се появява, както следва:
const векторВ този тип вектор не може да се добавя или премахва елемент. Освен това не може да се променя никаква стойност.
Конструиране с Iterator
Шаблонът предоставя родово представяне за тип данни. Итераторът осигурява общо представяне на сканирането през стойностите на контейнер. Синтаксисът за създаване на вектор с итератор е както следва:
шаблонвектор (InputIterator първи, InputIterator последен, const Allocator & = Allocator ());
Това изгражда вектор за диапазона [първи, последен), използвайки посочения разпределител, което ще бъде обсъдено по-късно в тази статия.
Унищожаване на вектор
За да унищожите вектор, просто го оставете да излезе извън обхвата и унищожаването се обработва автоматично.
Капацитет на вектора
size_type capacity () const noexcept
Общият брой елементи, които векторът може да съдържа, без да се изисква преразпределение, се връща от функцията член на капацитета. Кодов сегмент за това е както следва:
векторint num = vtr.капацитет();
Cout << num << '\n';
Изходът е 4.
резерв (n)
Пространството в паметта не винаги е свободно достъпно. Допълнително място може да се резервира предварително. Помислете за следния кодов сегмент:
векторvtr.резерв (6);
Cout << vtr.capacity() << '\n';
Изходът е 6. И така, запазеното допълнително пространство е 6 - 4 = 2 елемента. Функцията връща void.
size () const noexcept
Това връща броя на елементите във вектора. Следният код илюстрира тази функция:
векторплувка sz = vtr.размер ();
Cout << sz << '\n';
Изходът е 4.
смали до пасване()
След като придадете допълнителен капацитет на вектор с функцията reserve (), векторът може да бъде оразмерен, за да се побере до първоначалния му размер. Следният код илюстрира това:
векторvtr.резерв (6);
vtr.смали до пасване();
int sz = vtr.размер ();
Cout << sz << '\n';
Изходът е 4, а не 6. Функцията връща void.
преоразмеряване (sz), преоразмеряване (sz, c)
Това преоразмерява вектора. Ако новият размер е по-малък от стария, тогава елементите към края се изтриват. Ако новият размер е по-дълъг, тогава към края се добавя някаква стойност по подразбиране. За да добавите определена стойност, използвайте функцията resize () с два аргумента. Следният кодов сегмент илюстрира използването на тези две функции:
векторvtr1.преоразмеряване (2);
Cout << "New size of vtr1: " << vtr1.size() << '\n';
вектор
vtr2.преоразмеряване (4, 8.8);
Cout << "vtr2: "<< vtr2[0] <<" "<< vtr2[1] <<"
"<< vtr2[2] <<" "<< vtr2[3] << '\n';
Резултатът е следният:
Нов размер на vtr1: 2vtr2: 1.12.2 8.8 8.8
Функциите се връщат празно.
празен () const noexcept
Тази функция връща 1 за true, ако няма елементи във вектора и 0 за false, ако векторът е празен. Ако даден вектор има 4 местоположения за определен тип данни, като float, без никаква float стойност, тогава този вектор не е празен. Следният код илюстрира това:
векторCout << vtr.empty() << '\n';
вектор
Cout << vt.empty() << '\n';
вектор
Cout << v.empty() << '\n';
Резултатът е следният:
10
0
Достъп до векторни елементи
Векторът може да бъде скрипт (индексиран) като масив. Индексното броене започва от нула.
vectorName [i]
Операцията “vectorName [i]” връща препратка към елемента в iти индекс на вектора. Следният код извежда 3.3 за горния вектор:
векторfloat fl = vtr [2];
Cout << fl << '\n';
vectorName [i] const
Операцията “vectorName [i] const” се изпълнява вместо “vectorName [i]”, когато векторът е постоянен вектор. Тази операция се използва в следния код:
const векторплувка fl = vtr [2];
Cout << fl << '\n';
Изразът връща постоянна препратка към iти елемент на вектора.
Присвояване на стойност с индекс
Стойност може да бъде присвоена на непостоянен вектор, както следва:
векторvtr [2] = 8.8;
Cout << vtr[2] << '\n';
Изходът е 8.8.
vectorName.в (i)
“VectorName.при (i) “е като„ vectorName [i] “, но„ vectorName.at (i) ”е по-надежден. Следният код показва как трябва да се използва този вектор:
векторплувка fl = vtr.при (2);
Cout << fl << '\n';
at () е векторна член-функция.
vectorName.при (i) const
“VectorName.при (i) const “е като„ vectorName [i] const “, но„ vectorName.at (i) const ”е по-надежден. “VectorName.при (i) const “се изпълнява вместо„ vectorName.при (i) ”, когато векторът е постоянен вектор. Този вектор се използва в следния код:
const векторплувка fl = vtr.при (2);
Cout << fl << '\n';
at () const е векторна член-функция.
Присвояване на стойност с функцията at ()
Стойност може да бъде присвоена на непостоянен вектор с функцията at (), както следва:
векторvtr.при (2) = 8.8;
Cout << vtr[2] << '\n';
Изходът е 8.8.
Проблем с подскриптирането
Проблемът с подскриптирането (индексирането) е, че ако индексът е извън обхвата, може да се върне нула или да се издаде грешка по време на изпълнение.
отпред ()
Това връща препратка към първия елемент на вектора, без да се премахва елемента. Резултатът от следния код е 1.1.
векторплувка fl = vtr.отпред ();
Cout << fl << '\n';
Елементът не се премахва от вектора.
front () const
Когато векторната конструкция се предшества от const, изразът „front () const“ се изпълнява вместо „front ().”Това се използва в следния код:
const векторплувка fl = vtr.отпред ();
Cout << fl << '\n';
Връща се постоянна препратка. Елементът не се премахва от вектора.
обратно()
Това връща препратка към последния елемент на вектора, без да се премахва елемента. Резултатът от следния код е 4.4.
векторплувка fl = vtr.обратно();
Cout << fl << '\n';
back () const
Когато векторната конструкция се предшества от const, изразът „back () const“ се изпълнява вместо „back ().”Това се използва в следния код:
const векторплувка fl = vtr.обратно();
Cout << fl << '\n';
Връща се постоянна препратка. Елементът не се премахва от вектора.
Достъп до векторни данни
data () noexcept; data () const noexcept;
Всеки от тях връща указател, така че [data (), data () + size ()) е валиден диапазон.
Това ще бъде разгледано по-подробно по-нататък в статията.
Връщащи се итератори и вектор
Итераторът е като указател, но има повече функционалност от показалеца.
begin () noexcept
Връща итератор, който сочи към първия елемент на вектора, както в следния кодов сегмент:
векторвектор
Cout << *iter << '\n';
Изходът е 1.1. Имайте предвид, че декларацията, която получава итератора, е декларирана. Итераторът се деререферира в израз за връщане, за да се получи стойността по същия начин, по който се дереферира указател.
begin () const noexcept;
Връща итератор, който сочи към първия елемент на вектора. Когато векторната конструкция се предшества от const, изразът “begin () const” се изпълнява вместо “begin ().”При това условие съответният елемент във вектора не може да бъде модифициран. Това се използва в следния код:
const векторвектор
Cout << *iter << '\n';
Изходът е 1.1. Имайте предвид, че „const_iterator“ е използван този път вместо просто „итератор“, за да получи върнатия итератор.
end () noexcept
Връща итератор, който сочи непосредствено след последния елемент на вектора. Помислете за следния кодов сегмент:
векторвектор
Cout << *iter << '\n';
Резултатът е 0, което е безсмислено, тъй като няма конкретен елемент извън последния елемент.
end () const noexcept
Връща итератор, който сочи непосредствено след последния елемент на вектора. Когато векторната конструкция се предшества от „const“, изразът „end () const“ се изпълнява вместо „end ().”Помислете за следния кодов сегмент:
const векторвектор
Cout << *iter << '\n';
Изходът е 0. Имайте предвид, че „const_iterator“ е използван този път вместо просто „итератор“, за да получи върнатия итератор.
Обратна итерация
Възможно е да има итератор, който се итерира от края до непосредствено преди първия елемент.
rbegin () noexcept
Връща итератор, който сочи към последния елемент на вектора, както в следния кодов сегмент:
векторвектор
Cout << *rIter << '\n';
Изходът е 4.4.
Имайте предвид, че декларацията, която получава обратния итератор, е декларирана. Итераторът се деререферира в израз за връщане, за да се получи стойността по същия начин, по който се дереферира указател.
rbegin () const noexcept;
Връща итератор, който сочи към последния елемент на вектора. Когато векторната конструкция се предшества от „const“, изразът „rbegin () const“ се изпълнява вместо „rbegin ().”При това условие съответният елемент във вектора не може да бъде модифициран. Тази функция се използва в следния код:
const векторвектор
Cout << *rIter << '\n';
Изходът е 4.4.
Обърнете внимание, че const_reverse_iterator е бил използван този път, вместо само reverse_iterator, за да получи върнатия итератор.
rend () noexcept
Връща итератор, който сочи точно преди първия елемент на вектора. Помислете за следния кодов сегмент:
векторвектор
Cout << *rIter << '\n';
Резултатът е 0, което е безсмислено, тъй като няма конкретен елемент точно преди първия елемент.
rend () const noexcept
Връща итератор, който сочи точно преди първия елемент на вектора. Когато векторната конструкция се предшества от „const“, изразът „rend () const“ се изпълнява вместо „rend ().”Помислете за следния кодов сегмент:
const векторвектор
Cout << *rIter << '\n';
Изходът е 0.
Имайте предвид, че const_reverse_iterator е бил използван този път, вместо само reverse_iterator, за да получи върнатия итератор.
Векторни модификатори
Модификатор, който модифицира вектора, може да вземе или върне итератор.
а.emplace (p, аргументи)
Вмъква обект от тип T, конструиран със std :: forward
вмъкване (iteratorPosition, стойност)
Вмъква копие на стойността в позицията на итератора на вектора. Връща итератора (позиция) във вектора, където е поставено копието. Следният код показва къде е поставена стойността:
векторвектор
++iter;
++iter;
vtr.вложка (итер, 25);
Cout << vtr[1] << " << vtr[2]<< '
' << vtr[3] << '\n';
Резултатът е: 20 25 30.
Имайте предвид, че итераторът е усъвършенстван (увеличен) точно като указател.
Може да се добави и инициализационен списък, както илюстрира следният код:
векторвектор
++iter;
++iter;
vtr.вмъкване (iter, 25, 28);
Cout << vtr[1] << " << vtr[2]<< '
' << vtr[3]<< " << vtr[4] << '\n';
Резултатът е: 20 25 28 30.
изтриване (позиция)
Премахва елемент в позицията, посочена от итератора, след което връща позицията на итератора. Следният код илюстрира това:
векторвектор
++iter;
++iter;
vtr.изтриване (iter);
Cout << vtr[0] << " << vtr[1] << '
' << vtr[2]<< '\n';
Резултатът е: 10 20 40
push_back (t), push_back (rv)
Използва се за добавяне на единичен елемент в края на вектора. Използвайте push_back (t), както следва:
векторvtr.push_back (5.5);
плувка fl = vtr [4];
Cout << fl << '\n';
Изходът е 5.5.
push_back (rv): - вижте по-късно.pop_back ()
Премахва последния елемент, без да го връща. Размерът на вектора се намалява с 1. Следният код илюстрира това:
векторvtr.pop_back ();
плувка sz = vtr.размер ();
Cout << sz << '\n';
Изходът е 3.
а.суап (б)
Два вектора могат да бъдат разменени, както е илюстрирано в следния кодов сегмент:
векторвектор
vtr1.суап (vtr2);
Cout << "vtr1: "<< vtr1[0] <<" "<< vtr1[1] <<"
"<< vtr1[2] <<" "<< vtr1[3] << '\n';
Cout << "vtr2: "<< vtr2[0] <<" "<< vtr2[1] <<"
"<< vtr2[2] <<" "<< vtr2[3] << '\n';
Резултатът е:
vtr1: 10 20 0 0vtr2: 1.12.2 3.3 4.4
Имайте предвид, че дължината на вектор се увеличава, ако е необходимо. Също така стойностите, които не са замествали, се заменят с някаква стойност по подразбиране.
изчисти ()
Премахва всички елементи от вектора, както илюстрира следният кодов сегмент:
векторvtr.ясно ();
Cout << vtr.size() << '\n';
Изходът е 0.
Равенство и релационни оператори за вектори
Операторът ==
Връща 1 за true, ако двата вектора имат еднакъв размер и съответните елементи са равни; в противен случай връща 0 за false. Например:
векторвектор
bool bl = U == V;
Cout << bl << '\n';
Изходът е 0.
The != Оператор
Връща 1 за true, ако двата вектора нямат еднакъв размер и / или съответните елементи не са равни; в противен случай връща 0 за false. Например:
векторвектор
bool bl = U!= V;
Cout << bl << '\n';
Изходът е 1.
The < Operator
Връща 1 за true, ако първият вектор е началното подмножество на втория вектор, като елементите на двете равни части са еднакви и в същия ред. Ако и двата вектора са с еднакъв размер и се движат отляво надясно и в първия вектор се срещне елемент, който е по-малък от съответния елемент във втория вектор, тогава 1 пак ще бъде върнат. В противен случай се връща 0 за false. Например:
векторвектор
bool bl = U
Изходът е 1. < does not include the case when the size and order are the same.
> Операторът
Се завръща !(U < V), where U is the first vector and V is the second vector, according to the above definitions.
The <= Operator
Връща U <= V, where U is the first vector and V is the second vector, according to the above definitions.
Операторът> =
Се завръща !(U <= V), where U is the first vector and V is the second vector, according to the above definitions.
Заключение
Вектор е пример за контейнер за последователност. Векторът е „по-добра“ форма на обикновения масив и е създаден от клас. Векторите имат методи, които се класифицират под: конструиране и присвояване, капацитет, достъп до елементи, достъп до данни, итератори, модификатори и числови претоварени оператори.
Има и други контейнери за последователност, наречени list, forward_list и array. Ако задачата включва чести вмъквания и изтривания в средата на последователността, тогава трябва да се използва списък или forward_list. Ако задачата включва чести вмъквания и изтривания в началото или края на последователността, тогава трябва да се използва deque. И така, векторите трябва да се използват само когато този вид операции не са важни.