1. 程式人生 > >C++標準模板庫學習筆記之序列容器(vector、array)

C++標準模板庫學習筆記之序列容器(vector、array)

序列容器以線性序列的方式儲存元素。五種標準的序列容器:array<T,N>,vector<T>,deque<T>,list<T>,forward_list<T>。

Array

array<T, N>是一個有N個T類元素的序列,類似於陣列。既然是陣列,那麼它沒法增加和刪除元素,在定義的時候就指定了型別和大小。

初始化:  

例子:array<int, 100> data;    //此處沒有進行初始化,得到的是不確定的值。

array<int, 100> data{};    //此處進行了初始化,得到了100個0。

呼叫成員函式fill可以將陣列的元素都置為同一個值。

例如:data.fill(10)。//將data的元素都置為10.

訪問元素:[]、at()

區別是at()做越界檢查。在明確知道不會越界的時候用[]效率更高。

size()方法可以知道陣列的大小。empty()方法可以知道陣列是否為空。

front()方法和back()方法分別返回陣列首元素和尾元素的引用。

陣列迭代器:begin和end方法可以返回指向陣列首元素和末尾元素後一個位置的迭代器。

使用方法:begin(data)、end(data)

注意,迭代器並沒有保留容器的任何資訊,即我們不知道這個迭代器指向的是一個array容器還是vector容器。

這裡的設計思想很重要:演算法是獨立於容器型別的

cbegin方法和cend方法:返回const迭代器。

rbegin方法和rend方法:得到指向最後一個元素的迭代器和第一個位置的前一個位置的迭代器。

array容器的比較:比較的前提:型別相同,容量相同。

array容器的賦值,可以將一個array容器的值賦給另一個,必須保證大小相同,型別相同。

Vector

vector容器是平時用的最多的,但是還是需要深入學習。vector容器是個動態陣列。

初始化

vector<T> vec;//此時vector容器中沒有元素,不會分配空間。新增第一個資料項以後才會分配空間

reverse()方法,用於設定vector容器的容量,vec.reverse(10)設定容器容量為10,如果容器原來的容量大於10,該語句不起作用。注意,容量和長度的差異,長度是現有資料的個數,而容量是最多能放多少個數據。同時還需要注意的是,reverse方法會重新分配記憶體,此時的記憶體地址可能會發生改變,迭代器操作的時候要特別注意。

vector<int> vec{1,2,3};    //初始化容器為1,2,3,此時size()為3,capacity也為3

vector<int> vec(20);    //初始化容器為20個0,此時size()為20,capacity也為20

vector<int> vec(10, 3);    //初始化容器為10個3,此時size()為10,capacity也為10

vector容器考慮到了記憶體分配的開銷問題,即在必要時分配。

size()檢視容器中現有的元素個數,capicity()檢視容器的容量。

當對容器進行push_back/insert/emplace_back/emplace時,vector容器的容量發生變化,在64位作業系統下VS2015環境下測得容器的容量會變為原來的1.5倍。

同樣是容器,對string容器進行這種操作時,發現其size和capacity是一樣的,即不會申請更大的空間,會不會是string物件的開銷比較大,超過了申請額外空間的開銷?

使用resize函式可以改變容器的大小,但同時會改變容器的值。減小容器的時候會去除超過resize大小的元素。

pop_back()方法:刪除容器末尾的元素。呼叫一次就使size減1,capacity不受影響。

訪問元素同Array:[]、at()。

vector容器的迭代器:

使用copy演算法新增元素:copy(),三個引數:迭代器start,迭代器end,元素存放的位置(輸出迭代器)

copy(begin(vec), end(vec), ostream_iterator<int>(cout, " "));    //將指向vec容器的迭代器輸出到標準輸出流中。

如果插入的是物件,emplace_back插入比push_back更高效。例子:

vector<string> v1;

v1.push_back("123");//此時會生成一個臨時物件,然後再將這個臨時物件挪到vector中。

v1.emplace_back("123");//而emplace_back方法則直接在容器中生成了字串物件。

emplace方法與insert方法:

前者比後者高效:對於物件型別,insert會生成臨時物件。

find方法:找尋指定的迭代器區間的第一個指定元素:

auto iter = find(begin(vec), end(vec), 1);    //從前往後找第一個1出現的地方,並返回。

刪除元素:

clear()方法可以移除所有元素。移除以後,容器size為0,capacity跟移除以前相同。

erase()方法:刪除容器中的元素。vec.erase(begin(vec))//刪除首元素

vec.erase(begin(vec), begin(vec)+3)//刪除前三個元素,返回一個迭代器

erase改變size,不會改變容器的capacity。

remove()方法刪除匹配到的元素:vec.remove(begin(vec), end(vec), 5);//刪除容器中值為5的元素,返回一個迭代器

remove以後不會減小size,它會將刪除的元素賦空。

今天就這麼多了。