C++學習——數組的替代品vector

模板類vectorc++

模板類vector相似於string類,也是一種動態數組。您能夠在運行階段設置vector對象的長度,可在末尾附加新數據,還可在中間插入新數據。基本上,它是使用new建立動態數組的替代品。實際上,vector類確實使用new和delete來管理內存,但這種工做是自動完成的。數組

這裏不深刻探討模板類意味着什麼,而只介紹一些基本的實用知識。首先,要使用vector對象,必須包含頭文件vector。其次,vector包含在名稱空間std中,所以您可以使用using編譯指令、using聲明或std::vector。第三,模板使用不一樣的語法來指出它存儲的數據類型。第四,vector類使用不一樣的語法來指定元素數。下面是一些示例:安全

#include<vector>
...
using namespace std;
vector<int> vi;
int n;
cin>>n;
vector<double> vd(n);

其中,vi是一個vector<int>對象,vd是一個vector<double>對象。因爲vector對象在您插入或添加值時自動調整長度,所以能夠將vi的初始長度設置爲零。但要調整長度,須要使用vector包中的各類方法。函數

通常而言,下面的聲明建立一個名爲vt的vector對象,它可存儲n_elem個類型爲typeName的元素:spa

 vector<typeName> vt(n_elem); c++11

其中參數n_elem能夠是整型常量,也能夠是整型變量。code

模板類array(C++11)對象

vector類的功能比數組強大,但付出的代價是效率稍低。若是您須要的是長度固定的數組,使用數組是更佳的選擇,但代價是不那麼方便和安全。有鑑於此,C++11新增了模板類array,它也位於名稱空間std中。與數組同樣,array對象的長度也是固定的,也使用棧(靜態內存分配),而不是自由存儲區,所以其效率與數組相同,但更方便,更安全。要建立array對象,須要包含頭文件array。array對象的建立語法與vector稍有不一樣:blog

#include <array>
...
using namespace std;
array<int ,5> ai;
array<double,4> ad={1.2,2.1,3.43,4.3};

推而廣之,下面的聲明建立一個名爲arr的array對象,它包含n_elem個類型爲typename的元素:索引

 array<typeName,n_elem> arr; 

與建立vector對象不一樣的是,n_elem不能是變量。

在C++11中,可將列表初始化用於vector和array對象,但在C++98中,不能對vector對象這樣作。

比較數組、vector對象和array對象

要了解數組、vector對象和array對象的類似和不一樣之處,最簡單的方式多是看一個使用它們的簡單示例

int main() {
    double a1[4] = { 1.2,2.4,3.6,4.8 };
    vector<double> a2(4);  //建立含4個元素的vector
    a2[0] = 1.0 / 3.0;
    a2[1] = 1.0 / 5.0;
    a2[2] = 1.0 / 7.0;
    a2[3] = 1.0 / 9.0;
    //c++11--建立並初始化數組對象
    array<double, 4> a3 = { 3.14,2.72,1.62,1.41 };
    array<double, 4> a4;
    a4 = a3;   //數組對象大小相同時可賦值
    //用數組表示法
    cout << "a1[2]: " << a1[2] << " at " << &a1[2] << endl;
    cout << "a2[2]: " << a2[2] << " at " << &a2[2] << endl;
    cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl;
    cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl;

    a1[-2] = 20.2;
    cout << "a1[-2]: " << a1[-2] << " at " << &a1[-2] << endl;
    cout << "a3[2]: " << a3[2] << " at " << &a3[2] << endl;
    cout << "a4[2]: " << a4[2] << " at " << &a4[2] << endl;

    return 0;
}

程序說明

首先,注意到不管是數組、vector對象仍是array對象,均可使用標準數組表示法來訪問各個元素。其次,從地址可知,array對象和數組存儲在相同的內存區域(即棧)中,而vector對象存儲在另外一個區域(自由存儲區或堆)中。第三,注意到能夠將一個array對象賦給另外一個array對象;而對於數組,必須逐元素複製數據。

接下來,下面一行代碼須要特別注意:

 a1[-2] = 20.2; 

索引-2是什麼意思呢?本章前面說過,這將被轉換爲以下代碼:

 *(a1-2) = 20.2; 

其含義以下:找到a1指向的地方,向前移兩個double元素,並將20.2存儲到目的地。也就是說,將信息存儲到數組的外面。與C語言同樣,C++也不檢查這種超界錯誤。在這個示例中,這個位置位於array對象a3中。其餘編譯器可能將20.2放在a4中,甚至作出更糟糕的選擇。這代表數組的行爲是不安全的。

vector和array對象可以禁止這種行爲嗎?若是您讓它們禁止,它們就能禁止。也就是說,您仍可編寫不安全的代碼,以下所示:

 a2[-2]=.5; a3[200] = 1.4 

然而,您還有其餘選擇。一種選擇是使用成員函數at()。就像可使用cin對象的成員函數getline()同樣,您也可使用vector和array對象的成員函數at():

 a2.at(1)=2.3; 

中括號表示法和成員函數at()的差異在於,使用at()時,將在運行期間捕獲非法索引,而程序默認將中斷。這種額外檢查的代價是運行時間更長,這就是C++讓容許您使用任何一種表示法的緣由所在。另外,這些類還讓您可以下降意外超界錯誤的機率。

相關文章
相關標籤/搜索