1. 程式人生 > >C++中陣列和vector的比較

C++中陣列和vector的比較

一、陣列

C++中陣列是一種內建的資料型別。

陣列是存放型別相同的物件的容器,陣列的大小確定不變,不能隨意向陣列中增加元素。

1、定義和初始化內建陣列

(1)陣列的大小不變,(a[d],d為陣列的維度),陣列的維度必須是一個常量表達式。定義陣列的時,必須指定陣列的型別和大小。

(2)初始化時,允許不指明陣列的維度,不指明維度,則編譯器根據陣列初始值的大小推測出維度;若指定維度,則初始值的個數要小於等於維度,當小於時,不足的部分為0(其實還是等於維度)。

1 int a[]={1,2,3};    //陣列a的大小為3;
2 int a[5]={1,2,3};    //等價於{1,2,3,0,0},大小為5
3 int
a[5]={1,2,3,4,5,6}; //錯誤,初始值過多

 還有一種特殊的情況:字元陣列。當用字串字面值去初始化陣列時,要注意字串字面值的後面還有一個空字元。也就是說,陣列的大小要等於字面值的大小加1。

特別注意:不允許拷貝和賦值------不能將陣列的內容拷貝給其他陣列作為初始值,也不能用陣列為其他陣列賦值。

1 int a[]={1,2,3};    
2 int a2[]=a;            //錯誤
3 a2=a;                //錯誤

 2、訪問陣列元素

陣列的索引是從0開始,如:包含10個元素的陣列a,其索引是從0到9而非1到10,若是a[10]則下標越界。

另外,使用陣列下標時,其型別是size_t,在標頭檔案cstddef中。

二、向量

C++中vector為類模板。

vector是型別相同的物件的容器,vector的大小可以變化,可以向陣列中增加元素。

1、定義和初始化vector物件

初始化的方式比較多,有如下幾種:

複製程式碼
1 vector<T> v1;                    //v1為空,執行預設初始化
2 vector<T> v2(v1);                //v2中包含v1所有元素的副本
3 vector<T> v2=v1;                //等價於v2(v1)
4 vector<T> v3(n,val);            //v3中包含n個重複元素,每個元素的值都是val
5 vector<T> v4(n); //v4包含n個重複執行了值初始化的物件 6 vector<T> v5{a,b,c...}; //包含初始化元素個數,每個元素被對應的賦予相應的值 7 vector<T> v5={a,b,c...}; //等價v5{a,b,c...}
複製程式碼

 注意事項:

(1)vector<T> v1,只用預設初始化時,不能通過下標進行新增元素。也就是說,當你將v1初始化為空時,假如你想向v1中新增10個元素,不能通過v1[2]=3;等形式新增,因為,別人為空,壓根不知道v1[2]是什麼東東。

(2)注意vector<T> v4(n)和vector<T> v4{n}的區別。前者說的是,v4中有n個相同的元素,至於值為多少要看相應物件的初始化值;而後者,則是說v4中只有一個元素,其值為n。

(3)不能使用包含著多個值的括號去初始化vector物件。注意和或括號的區別。

1 vector<int> intV(1,2,3);        //錯誤 

 2、向vector物件中新增物件

利用vector的成員函式push_back向其中新增物件:

1 vector<int> v;
2 for(int i=0;i !=100;++i)
3 {
4     v.push_back(i);
5 }

 注意:

若是迴圈體內包含想vector物件新增元素的語句,則不能使用範圍for迴圈。因為範圍for語句不應改變其所遍歷序列的額大小。原因如下:

複製程式碼
 1 vector<int> v={1,2,3,4,5,6,7,8,9};
 2 for(auto &r: v)
 3 {
 4     r*=2;
 5 }
 6 
 7 等價於
 8 for(auto beg=v.begin(),end=v.end();beg !=end;++beg)
 9 {
10     auto &r=*beg;
11     r*=2;
12 }
複製程式碼

 即在範圍for語句中,預存了end()的值,一旦在序列中新增(刪除)元素,end函式的值就可能變的無效了。

3、vector的擴容、插入和刪除

(1)擴容

vector的底層資料結構時陣列。

當vector中的可用空間耗盡時,就要動態第擴大內部陣列的容量。直接在原有物理空間的基礎上追加空間?這不現實。陣列特定的地址方式要求,物理空間必須地址連續,而我們無法保證其尾部總是預留了足夠空間可供拓展。一種方法是,申請一個容量更打的陣列,並將原陣列中的成員都搬遷至新空間,再在其後方進行插入操作。新陣列的地址由OS分配,與原資料區沒有直接的關係。新陣列的容量總是取作原陣列的兩倍

(2)插入和刪除

插入給定值的過程是,先找到要插入的位置,然後將這個位置(包括這個位置)的元素向後整體移動一位,然後將該位置的元素複製為給定值。刪除過程則是將該位置以後的所有元素整體前移一位。

(2)vector的size和capacity

size指vector容器當前擁有的元素個數,capacity指容器在必須分配新儲存空間之前可以儲存的元素總數,capacity總是大於或等於size的。

三、陣列與vector的對比

1、記憶體中的位置

C++中陣列為內建的資料型別,存放在中,其記憶體的分配和釋放完全由系統自動完成;vector,存放在中,由STL庫中程式負責記憶體的分配和釋放,使用方便。

2、大小能否變化

陣列的大小在初始化後就固定不變,而vector可以通過push_back或pop等操作進行變化。

3、初始化

陣列不能將陣列的內容拷貝給其他陣列作為初始值,也不能用陣列為其他陣列賦值;而向量可以。

4、執行效率

陣列>vector向量。主要原因是vector的擴容過程要消耗大量的時間。