C Primer 陣列部分

2021-08-17 10:10:22 字數 3208 閱讀 9019

陣列是一種復合型別,與vector類似陣列也是存放型別相同的物件的容器(所以不能存放引用),這些物件沒有名字,需要通過其位置訪問。陣列本身是乙個物件。

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

首先是陣列的宣告,陣列的宣告形如 a[d] ,其中a是陣列的名字,d是陣列的維度,維度必須是乙個常量表示式,且必須大於0;

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

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

char a1 = "c++";                     //會新增表示字串結束的空字元

char a2 = ; //等價於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 = ;

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物件:

vectorivec(begin(int_arr),end(int_arr));

vectorsubvec(int_arr + 1,int_arr + 4);      //三個元素 int_arr[1]、int_arr[2]、int_arr[3]
多維陣列:陣列的陣列

多維陣列的初始化:

int a[3][4] = ,

,};

等價於:

int a[3][4] = ;
在遍歷多維陣列的時候要注意:在很多用到陣列名字的地方,編譯器都會自動地將其替換為乙個指向陣列首元素的指標。

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

for (auto row : ia)

for(auto col : row)

本部分留下的問題:

陣列不是 類 型別?

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

C primer 部分術語

c primer 可謂是經典的不能在經典的一本書 這本書的每一章節背後都有些術語,我按順序摘抄了些.以後補全 c primer 術語 第一章 argument 實參 block 塊 buffer 緩衝區 built in type 內建型別 cerr cinclass 類 class type 類型...

c primer 函式部分總結

1,實參是函式形參的初始值,函式的每次呼叫都要經歷形參的初始化過程 每次呼叫函式都會重新建立它的形參 並且實參的數量必須與形參相匹配或者實參的型別能轉換成形參的型別。2,函式的返回型別不能使陣列和函式,但是可以是函式的指標和指向陣列的指標,返回型別可以是void。3,形參 也定義與函式體內部 和函式...

C Primer基礎部分總結(2)

東陽的學習記錄 給空語句加上注釋 多餘的空語句並非總是無害的 switch語句中的case標籤必須是整型常量表示式 任何兩個case標籤的值不能相同 case分支後若沒有break,最好注釋說明 如果某個case分支需要定義區域性變數,請把區域性變數置於內 為了防止出現未初始化就使用的情況 whil...