C++之數組總結

數組

數組(array)是一種數據格式,能夠存儲多個同類型的值。每個值都存儲在一個獨立的數組元素中,計算機在內存中依次存儲數組的各個元素。要創建數組,可使用聲明語句。數組聲明應指出以下三點:

  • 存儲在每個元素中的值的類型;
  • 數組名
  • 數組中的元素數

在C++中,可以通過修改簡單變量的聲明,添加中括號(其中包含元素數目)來完成數組聲明。例如,下面的聲明創建一個名爲 months的數組,該數組有12個元素,每個元素都可以存儲一個 short類型:

short months[12]

聲名數組的通用格式如下

typeName arrayName[arraySize];

​表達式 arraySize指定元素數目,它必須是整型常數(如10)或const值,也可以是常量表達式(如8·
sizeof(int),即其中所有的值在編譯時都是已知的。具體地說, arraySize不能是變量,變量的值是在程序時設置的。

​數組的很多用途都是基於這樣一個事實:可以單獨訪問數組元素,方法是使用下標或索引來對元素進行編號。C++數組從0開始編號。C++使用帶索引的方括號表示法來指定數組元素,例如, months[0]是 months數組的第一個元素, months[11]是最後一個元素。注意,最後一個元素的索引比數組長度小1(參見圖1)。因此,數組聲明能夠使用個聲明創建大量的變量,然後便可以用索引來標識和訪問各個元素

數組的初始化規則

只有定義數組時才能使用初始化,此後就不能使用了,也不能將一個數組賦給另一個數組:

int cards[4] = {3,6,8,10};    //okay
int hand[4];                  //okay
hand[4] = {5,6,7,9};          //not okay
hand = cards;                 // not okay

也可以使用下標分別給數組中的元素賦值。

初始化數組時,提供的值可以少於數組的元素數目。例如,下面的語句只初始化hotelTips的前兩個元素:

float hotelTips[5] = {5.0,2.5};

如果只對數組的一部分進行初始化,則編譯器將把其他元素設置爲0.因此,將數組中所有的元素都初始化爲0非常簡單—只要顯式地將第一個元素初始化爲0,然後讓編譯器將其他元素都初始化爲0;

long totals[500] = {0};

如果初始化爲{1} 而不是{0},則第一個元素設置爲1,其他元素被設置爲0。

如果初始化數組時方括號內([])爲空,C++編譯器將計算元素個數,例如,對於下面的聲名:

short things[] = {1, 5, 3, 8}

編譯器將使things數組包含4個元素。

C++11初始化方法

C++使用大括號的初始化(列表初始化)作爲一種通用初始化方法,可用於所有類型。數組以前就可使用列表初始化,但C++中列表初始化新增了一些功能。

1.初始化數組時,可以省略等號(=)

double earnings[4] {1.2e4,1.6e4,1.1e4,1.7e4};

2.可在大括號內不包含任何東西,這將把所有元素都設置爲零:

unsigned int counts[10]={}; //all elements set to 0
float balances[100] {}      //all elements set to 0

3.列表初始化禁止縮窄轉換

long plifs[] = {25,92,3.0}   // not allowed
char slifs[4] {'h','i',1122011,'\0'} // not allowed
char tlifs[4] {'h','i',112,'\0'}   //allowed

在上述代碼中,第一條語句不能通過編譯,因爲將浮點數轉換爲整型是縮窄操作,即使浮點數的小數點後面爲零。第二條語句也不能通過編譯,因爲1122011超出了char變量的取值範圍(這裏假設char變量的長度爲8位)。第三條語句可通過編譯,因爲雖然112是一個int值,但它在char變量的取值範圍內。

數組的替代品

模板類vector和array是數組的替代品;這些替代品對於數組的創建和使用更加靈活簡便。

模板類vector

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

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

#include <vector>
...
usinga namespace std;
vector<int> vi;   //創建一個長度爲零的int型數組
int n;
cin >> n;
vector<double> vd(n);  //創建一個大小爲n的double型數組

其中,vi是一個 vector對象,vd是一個 vector對象。由於 vector對象在插入或添加值時自動調整長度,因此可以將vi的初始長度設置爲零。但要調整長度,需要使用vector包中的各種方法。

一般而言,下面的聲明創建一個名爲vt的vector對象,它可存儲n_elem個類型爲type_Name的元素:

vector<typeName> vt(n_elem);

其中參數n_elem可以是整型常量,也可以是整型變量。

模板類array(C++11)

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

#include <array>
...
using namespace std;
array<int, 5> ai;   //創建一個大小爲5的array對象
array<double, 4> ad = {1.2, 2.1, 3.43, 4.3};

推而廣之,下面的聲名創建一個名爲arr的array的對象,它包含n_elem個類型爲typeName的元素:
```C++
array<typeName, n_elem> arr;

與創建veto對象不同的是,n_elem不能是變量,在C++11中,可將列表初始化用於vector和array對象,但在C++98中,不能對vector對象這樣做.

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

要了解數組、 vector對象和aray對象的相似和不同之處,最簡單的方式可能是看一個使用它們的簡單示例:

#include iostream>
include <vector> //STL C++98
#include <array> //C++11
int main()
{
    using namespace std;
    //C, original C++
    double a1[4]={1.2,2.4,3.6,4,8};
    //C++98sTL 
    vector<double> a2(4); // create vector with 4 element
    // no simple way to initialize in C98
    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-- create and initialize array object       
    array<double,4> a3 = {3.14,2.72,1.62,1,41};
    array<double, 4> a4;
    a4=a3;  //valid for array objects of same size
    // use array notation 
    cout<<"a1[2]:"<<a1[2]<<"at"<<&a1[2]<<end1;
    cout<<"a2[2]:"<<a2[2]<<"at"<<&a2[2l<<endl; 
    cout<<"a3[2]:"<<a[2]<<"at"<<&a3[2]<<endl;cout<<"a4[2]:"<<a4[2]<<"at"<<&a4[2]<end1
    // misdeed 
    a1[-2]=20.2; 
    cout<<"a1[-2]:"<<a1[2]<<"at"<&a1[-2]<<endl;
    cout<<"a3[2]:"<<a3[2l<<"at"<&a3[2]<<endl;cout<<"a4[2]:"<<a4[2]<<"at"c&a4[2<<endl;
    ruturn 0;
}
//程序輸出
a1[2]:3,6 at 0x28cce8
a2[2]:0.142857 at 0xca0328
a3[2]:1.62 at 0x28ccc8
a4[2]:1.62 at 0x28cca8
a1[-2]:20.2 at 0x28ccc8
a3[2]:20.2 at 0x2BcccB 
a4[2]:1.62 at 0x28ccaB

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

下面有一行代碼需要特別注意:

a1[-2] = 20.2;

這個索引將被轉換爲如下代碼:

*[a1-2] = 20.2;

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章