C++Primer 數組部分

數組是一種複合類型,與vector類似數組也是存放類型相同的對象的容器(所以不能存放引用),這些對象沒有名字,需要通過其位置訪問。數組本身是一個對象。

與vector不同的是數組的大小是固定的,不能隨意的向數組中增加元素。

首先是數組的聲明,數組的聲明形如 a[d] ,其中a是數組的名字,d是數組的維度,維度必須是一個常量表達式,且必須大於0;

默認情況下,數組中的元素會被默認初始化,和內置類型的變量一樣,如果在函數內部定義了某種內置類型的數組,那麼默認初始化會令數組含有未定義的值。在定義數組時,必須指定數組的類型,不允許用auto關鍵字有初始值的列表推斷類型。

在使用字符串字面值對數組初始化的時候,注意字符串字面值的結尾處還有一個空字符,這個空字符也會像被拷貝到字符數組中去。

char a1[] = "C++";                     //會添加表示字符串結束的空字符
char a2[] = {'C','+','+','\0'};        //等價於a1,含有顯式的空字符

讓我們來看看書中幾個數組的聲明:

int *ptrs[10];                         //定義了一個存放了10個指向int類型的指針,名爲ptr的數組
int &refs[10] = /* ? */;               //illegal,數組中存放的是對象,而引用只是變量的別名,不是一個對象
int(*Parray)[10] = &arr;               //從內部向外理解數組的定義,首先看*Parray,這意味着Parray是一個指針,然後看右邊,可知Parray指向的是一個大小爲10的數組,接下來看左邊,可知數組中的元素類型爲int,其中arr爲數組名,&爲取地址運算符
int (&arrRef)[10] = arr;               //arrRef是一個綁定了一個含有10個int類型元素的數組,其中arr爲數組名

與vector和string一樣,數組的元素也可以通過 範圍 for 語句或下標運算符來訪問,數組的索引從0開始。數組的下標通常被定義爲size_t類型。size_t是一種機器相關的無符號類型,它被設計得足夠大以便能表示內存中任意對象的大小,在cstddef頭文件中定義。

在使用數組的時候編譯器一般會把他轉換成指針

和其他對象一樣,對數組的元素使用取地址符就能得到指向該元素的指針:

string nums[] = {"one","two","three"};
string *p = &nums[0];

然而數組還有一個特性:在很多用到數組名字的地方,編譯器都會自動地將其替換爲一個指向數組首元素的指針:

string *p2 = nums;                    //等價於 string *p2 = &nums[0]

在大多數的表達式中,使用數組類型的對象其實是使用一個指向該數組首元素的指針。(沒看懂什麼意思)

例如:使用數組作爲一個auto變量的初始值時,推斷得到的類型是指針而非數組。

int a[10];
auto a2(a);                           //a2是一個整型指針,指向a第一個元素。等價於 auto a2(&a[0]);

當使用decltype關鍵字是上述轉換不會發生,decltype(a)返回的類型是有10個整數構成的數組。

可以定義一個指向數組的尾後元素的指針來完成對數組的循環,但是這樣極容易出錯,因爲尾後元素不是實際存在的,所以如果對尾指針進行解引用或者遞增操作會發生不可預知的錯誤。

標準庫函數begin和end:

begin和end這兩個函數被定義在iterator頭文件中,作用是返回數組首元素的指針和數組尾後元素的指針。由於數組不是類類型,因此這兩個函數不是成員函數,正確的使用形式是將數組作爲他們的參數

指針運算:

兩指針相減的結果是他們之間的距離,參與運算的兩個指針必須指向同一數組當中的元素,而該結果的類型爲 定義在cstddef頭文件中的ptrdiff_t類型,它是一種帶符號的類型。

如果p是空指針,允許,給p加上或減去一個值爲0的整型常量表達式。兩個空指針也允許彼此相減,結果當然是0.(有什麼用呢?)

對數組執行下標運算其實就是對指向數組元素的指針執行下標運算:

int  i= a[2];
//等價於
int *p = a[];
i = *(p+2);
//
int j = p[1];                      //等價於*(p+1)
int k = p[-2];                     //等價於*(p-2)

有關C風格字符串的問題,問題焦點就是C語言中的字符串是一個元素類型char的數組,而C++中的字符串卻是一個string類型,

很多string的內置操作不能用在char上。(猜的)

使用數組初始化vector對象:

只需要指明拷貝區域的首元素地址和尾後地址:

vector<int> ivec(begin(int_arr),end(int_arr));

vector<int> subVec(int_arr + 1,int_arr + 4);      //三個元素 int_arr[1]、int_arr[2]、int_arr[3]

多維數組:數組的數組

多維數組的初始化:

int a[3][4] = {
{0,1,2,3},
{4,5,6,7},
{8,9,10,11}
};

等價於:

int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

在遍歷多維數組的時候要注意:在很多用到數組名字的地方,編譯器都會自動地將其替換爲一個指向數組首元素的指針。

所以在下面的代碼中,即使我們沒有要修改數組元素的值,但是編譯器在初始化row時,會自動將這些數組形式的元素轉換成指向該數組內首元素的指針:

for (auto row : ia)
    for(auto col : row)


本部分留下的問題:

數組不是 類 類型?

如果p是空指針,允許,給p加上或減去一個值爲0的整型常量表達式。兩個空指針也允許彼此相減,結果當然是0.(有什麼用呢?)



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