內(nèi)蒙古城鄉(xiāng)建設(shè)網(wǎng)站換名字了網(wǎng)絡(luò)推廣渠道都有哪些
?????????本篇我們來介紹STL的vector的內(nèi)容。vector其實就是順序表,vector的學(xué)習(xí)還是分為接口使用和模擬實現(xiàn)兩大部分,本片就是介紹一下vector的使用。
1.vector的介紹及使用
vector文檔介紹:vector - C++ Reference? 在使用時需要加頭文件#include <vector>.
vector是一個標(biāo)準(zhǔn)的模板。不知道什么是模板去看【C++】模板(初識):函數(shù)模板、類模板-CSDN博客
第一個模板參數(shù)是要存的數(shù)據(jù)類型,第二個模板參數(shù)是一個空間配置器,就是一個內(nèi)存池,現(xiàn)在不用關(guān)心他是什么。?
我們在vector學(xué)習(xí)時一定要學(xué)會查文檔。
string因為一些發(fā)展歷史的原因,設(shè)計的接口比較多,比較冗余,vector相對來說就好很多,接口比string少很多。我們還是重點說經(jīng)常使用的接口。
2.vector的構(gòu)造函數(shù)、析構(gòu)函數(shù)和operator=
構(gòu)造函數(shù)
比如說下面的存int類型的順序表。
vector<int> v1; //無參構(gòu)造
vector<int> v2(10, 1); //10個1初始化
vector<int> v3(v2.begin(), v2.end());//迭代器區(qū)間初始化
vector<int> v4(++v2.begin(), --v2.end());//迭代器區(qū)間初始化
析構(gòu)函數(shù)自動調(diào)用。
?
賦值運算符重載。
vector<int> v1; //無參構(gòu)造
vector<int> v2(10, 1); //10個1初始化
vector<int> v3(v2.begin(), v2.end());//迭代器區(qū)間初始化
vector<int> v4(++v2.begin(), --v2.end());//迭代器區(qū)間初始化
v4 = v2; //v2,v4已存在,是賦值
3.vector的遍歷
vector的遍歷和string一樣有三種方式:下標(biāo)遍歷、迭代器、范圍for。這三種遍歷詳細(xì)的介紹在string類里面【C++】string類接口使用(萬字詳解)_sting怎么用-CSDN博客?第2.5節(jié)(string類對象的訪問及遍歷操作),不管是string還是vector,迭代器和范圍for的用法都是一樣的,類域不同而已,如果不清楚的建議先看string的2.5節(jié)。
3.1 下標(biāo)遍歷
vector<int> v2(10, 1); //10個1初始化
for (int i = 0; i < v2.size(); i++)
{cout << v2[i] << " ";
}
cout << endl;
因為vector也重載了operator[],所以也可以通過下標(biāo)遍歷。
3.2 迭代器
vector<int> v2(10, 1); //10個1初始化
vector<int>::iterator it = v2.begin();
while (it != v2.end())
{cout << *it << " ";++it;
}
cout << endl;
這里vector的迭代器要指定vector::類域,我們說string的迭代器的時候也是指定了string::類域。
反向迭代器和const迭代器就不演示了。?
3.3 范圍for
vector<int> v2(10, 1); //10個1初始化
for (auto e : v2)
{cout << e << " ";
}
cout << endl;
?
?
4.reserve
這個部分別的接口就不多說了,看一眼就知道是什么。我們來說一下reserve擴容。
?用法大家都知道,我們看一下擴容機制,是不是一直按1.5倍擴。
void TestVectorExpandOP()
{vector<int> v;size_t sz = v.capacity();cout << "making bar grow:\n";for (int i = 0; i < 100; ++i){v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "capacity changed: " << sz << '\n';}}
}
int main()
{TestVectorExpandOP();return 0;
}
大概是1.5倍,有的地方做了特殊處理,比如向上取整,向下取整。
解決辦法就是提前開空間,提前就開100個。
void TestVectorExpandOP()
{vector<int> v;size_t sz = v.capacity();v.reserve(100); // 提前將容量設(shè)置好,可以避免一遍插入一遍擴容cout << "making bar grow:\n";for (int i = 0; i < 100; ++i){v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "capacity changed: " << sz << '\n';}}
}
同樣的,我們傳n過去,編譯器會開大于等于n的空間。
但是對于下面的第二種情況,string和vector處理方式不同。
?
5.resize
reserve是絕對不會改變size的,只會對capacity產(chǎn)生影響,但是resize會改變size,還會改變capacity。
?
?第二個參數(shù)val傳的話,多出來的所有都存為val。直接代碼演示。
vector<int> v(10, 1);//10個1初始化
v.resize(5); //n<size情況
?
vector<int> v(10, 1);//10個1初始化
v.reserve(20);//開20個空間
//size < n < capacity,不傳第二個參
v.resize(15);
?
vector<int> v(10, 1);//10個1初始化
v.reserve(20);//開20個空間
//size < n < capacity,傳第二個參
v.resize(15, 2);
vector<int> v(10, 1);//10個1初始化
v.reserve(20);//開20個空間
//n > capacity,不傳第二個參
v.resize(23);
?
vector<int> v(10, 1);//10個1初始化
v.reserve(20);//開20個空間
//n > capacity,傳第二個參
v.resize(23, 2);
?resize大概就是這樣。
6.insert和erase
尾插和尾刪就不多說了,這里說一下insert。
vector的insert不支持下標(biāo)了,都是迭代器。
vector<int> v(10, 1);
v.insert(v.begin(), 2);//頭插
v.insert(v.end(), 3);//尾插
?
vector<int> v(10, 1);
v.insert(v.begin(), 2);//頭插
v.insert(v.end(), 3);//尾插
v.insert(v.begin() + 3, 4);//第3個位置插入
?
?
?erase也不支持下標(biāo),只支持迭代器。
vector<int> v(10, 1);
v.insert(v.begin(), 2);//頭插
v.insert(v.end(), 3);//尾插
v.insert(v.begin() + 3, 4);//第3個位置插入
v.erase(++v.begin());//刪第2個位置數(shù)據(jù)
?
7.vector支持流插入和流提取嗎?
不支持。我們會發(fā)現(xiàn)vector文檔里面并沒有重載<<和>>,因為vector的輸入輸出有很多不確定性。
這個要注意一下。
別的接口就不多說了,很多和string接口用法一致。所以一定要打好string的基礎(chǔ),vector學(xué)起來就比較輕松?!綜++】string類接口使用(萬字詳解)_sting怎么用-CSDN博客