1、vector容器基本概念
vector是一種單口的容器,又稱單端動態數組,vector所指的內容是一片連續的空間,支持隨機訪問(Random Access),此外,vector容器的空間是動態增長的。
2、vector容器本質及其實現
vector的數據安排以及操作方式,與array非常相似。兩者的唯一差別在于空間的運用的靈活性。
Array是靜態空間,一旦配置了就不能改變,要換大一點或者小一點的空間,可以,一切瑣碎得由自己來,首先配置一塊新的空間,然后將舊空間的數據搬往新空間,再釋放原來的空間。
Vector是動態空間,隨著元素的加入,它的內部機制會自動擴充空間以容納新元素。因此vector的運用對于內存的合理利用與運用的靈活性有很大的幫助,我們再也不必害怕空間不足而一開始就要求一個大塊頭的array了。
Vector的實現技術,關鍵在于其對大小的控制以及重新配置時的數據移動效率,一旦vector舊空間滿了,如果客戶每新增一個元素,vector內部只是擴充一個元素的空間,實為不智,因為所謂的擴充空間(不論多大),一如剛所說,是”配置新空間-數據移動-釋放舊空間”的大工程,時間成本很高,應該加入某種未雨綢繆的考慮,稍后我們便可以看到vector的空間配置策略。
vector的未雨綢繆機制:當容器滿的時候 會另辟一段空間(大小為2的N次方),將舊空間 的內容 復制 到新空間 然后釋放舊空間。
3、 vector迭代器
Vector維護一個線性空間,所以不論元素的型別如何,普通指針都可以作為vector的迭代器,因為 vector迭代器所需要的操作行為,如operator, operator->, operator++, operator--, operator+, operator-, operator+=, operator-=, 普通指針天生具備。
Vector支持隨機存取,而普通指針正有著這樣的能力。所以vector提供的是隨機訪問迭代器(Random Access Iterators).
使用案例:
#define _CRT_SECURE_NO_WARNINGS #include<iostream>#include<vector> using namespace std; int main(){
vector<int> v;
for (int i = 0; i < 10;i ++)
{
v.push_back(i);
cout << v.capacity() << endl; // v.capacity()容器的容量
}
system("pause");
return EXIT_SUCCESS; }
4、 vector的數據結構
Vector所采用的數據結構非常簡單,線性連續空間,它以兩個迭代器Myfirst和Mylast分別指向配置得來的連續空間中目前已被使用的范圍,并以迭代器_Myend指向整塊連續內存空間的尾端。 為了降低空間配置時的速度成本,vector實際配置的大小可能比客戶端需求大一些,以備將來可能的擴充,這邊是容量的概念。換句話說,一個vector的容量永遠大于或等于其大小,一旦容量等于大小,便是滿載,下次再有新增元素,整個vector容器就得另覓居所。
注意: 所謂動態增加大小,并不是在原空間之后續接新空間(因為無法保證原空間之后尚有可配置的空間),而是一塊更大的內存空間,然后將原數據拷貝新空間,并釋放原空間。因此,對vector的任何操作,一旦引起空間的重新配置,指向原vector的所有迭代器就都失效了。這是程序員容易犯的一個錯誤,務必小心。
5、vector常用API操作
5.1vector構造函數
vector<T> v; //采用模板實現類實現,默認構造函數 vector(v.begin(), v.end());//將v[begin(), end())區間中的元素拷貝給本身。 vector(n, elem);//構造函數將n個elem拷貝給本身。 vector(const vector &vec);//拷貝構造函數。 //例子 使用第二個構造函數 我們可以... int arr[] = {2,3,4,1,9};
vector<int> v1(arr, arr + sizeof(arr) / sizeof(int));
5.2vector常用賦值操作
assign(beg, end);//將[beg, end)區間中的數據拷貝賦值給本身。 assign(n, elem);//將n個elem拷貝賦值給本身。
vector& operator=(const vector &vec);//重載等號操作符 swap(vec);// 將vec與本身的元素互換。
5.3vector大小操作
size();//返回容器中元素的個數 empty();//判斷容器是否為空 resize(int num);//重新指定容器的長度為num,若容器變長,則以默認值填充新位置。如果容器變短, 則末尾超出容器長度的元素被刪除。 resize(int num, elem);//重新指定容器的長度為num,若容器變長,則以elem值填充新位置。如果容 器變短,則末尾超出容器長>度的元素被刪除。 capacity();//容器的容量 reserve(int len);//容器預留len個元素長度,預留位置不初始化,元素不可訪問。
5.4vector數據存取操作
at(int idx); //返回索引idx所指的數據,如果idx越界,拋出out_of_range異常。operator[];//返回索引idx所指的數據,越界時,運行直接報錯 front();//返回容器中第一個數據元素 back();//返回容器中最后一個數據元素.
5.5vector插入和刪除操作
insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count個元素ele. push_back(ele); //尾部插入元素elepop_back();//刪除最后一個元素 erase(const_iterator start, const_iterator end);//刪除迭代器從start到end之間的元素 erase(const_iterator pos);//刪除迭代器指向的元素 clear();//刪除容器中所有元素
6、vector使用案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
for (int i = 0; i < 100000;i ++)
{
v.push_back(i);
}
cout << "capacity:" << v.capacity() << endl;
cout << "size:" << v.size() << endl;
//此時 通過resize改變容器大小
v.resize(10);
cout << "capacity:" << v.capacity() << endl;
cout << "size:" << v.size() << endl;
//容量沒有改變
vector<int>(v).swap(v);
cout << "capacity:" << v.capacity() << endl;
cout << "size:" << v.size() << endl;
system("pause");
return EXIT_SUCCESS; }
6.2reserve預留空間
如果調用reserve函數預留出足夠的空間,可以大大降低空間開辟次數。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
//預先開辟空間
//v.reserve(100000);
int* pStart = NULL;
int count = 0;
for (int i = 0; i < 100000;i ++)
{
v.push_back(i);
if (pStart != &v[0])
{
pStart = &v[0];
count++;
}
}
cout << "count:" << count << endl;
system("pause");
return EXIT_SUCCESS;
}
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
//預先開辟空間
v.reserve(100000);
int* pStart = NULL;
int count = 0;
for (int i = 0; i < 100000;i ++)
{
v.push_back(i);
if (pStart != &v[0])
{
pStart = &v[0];
count++;
}
}
cout << "count:" << count << endl;
system("pause");
return EXIT_SUCCESS;}
更多關于“物聯網培訓”的問題,歡迎咨詢千鋒教育在線名師。千鋒教育多年辦學,課程大綱緊跟企業需求,更科學更嚴謹,每年培養泛IT人才近2萬人。不論你是零基礎還是想提升,都可以找到適合的班型,千鋒教育隨時歡迎你來試聽