C Primer(四)陣列和指標

2021-06-22 10:57:13 字數 4409 閱讀 5386

陣列定義中的型別名可以是內建型別或者類型別,除引用之外,陣列元素的型別還可以是任意的復合型別。沒有所有元素都是引用的陣列

陣列的維數必須用值大於1的常量表示式定義。此常量表示式只能包含整型字面值、列舉常量或者用常量表示式初始化的整型const物件。非const變數以及要到執行時才知道其值的const變數都不能用於定義陣列的維數

1.顯示初始化陣列元素

如果沒有顯示提供元素初值,則陣列元素會像普通變數一樣初始化:

在函式體外定義的陣列,其元素被初始化為0

在函式體內定義的陣列,其元素無初始化

不管陣列**定義,如果其元素型別是類型別,則自動呼叫該類的預設建構函式進行初始化;如果該類沒有預設建構函式,則必須為該陣列提供顯示初始化

顯示初始化的陣列不需要指定陣列的維數值,編譯器會根據列出的元素個數來確定陣列長度;

int a=;

2. 特殊的字元陣列

字元陣列既可以引用一組由花括號括起來、逗號隔開的字元字面值進行初始化,也可以用乙個字串字面值進行初始化。當使用字串字面值來初始化建立的新陣列時,將在陣列中加入空字串

3. 不允許陣列直接複製和賦值

與vector不同,乙個陣列不能用另乙個陣列初始化,也不能將乙個陣列賦值到另乙個陣列,這些操作是非法的

注意:陣列一經定義,就不允許再新增新元素

每個指標都有乙個與之關聯的資料型別,該資料型別決定了指標所指向的物件的型別。

4.  指標可能的取值

若指標儲存0值,表明它不指向任何物件。未初始化的指標是無效的。直到給該指標賦值後才可使用它。

5.避免使用未初始化的指標

若果使用未初始化的指標,會將指標中存放的不確定值視為位址,然後操縱該記憶體位址中的存放的內容。

6.對指標進行初始化或者賦值只能使用以下四種型別的值:

(1)0值常量表示式。例如:在編譯時可獲得的0值得整型const物件或者字面值常量0.

(2)型別匹配的物件的位址

(4)同型別的另乙個有效的指標

允許把數值0或在編譯時可獲得0值得const量賦給指標

由於指標的型別用於確定指標所指的物件的型別,因此初始化或者賦值時必須保證型別匹配

7. void*指標

void*指標只支援幾種有限的操作:與另乙個指標進行比較;向函式傳遞void *指標或者返回void *指標;給另外乙個void *指標賦值。不允許使用void *指標操縱它所指向的物件。

指標提供間接操縱其所指物件的功能。

2. 指標和引用的比較

引用和指標之間有兩個重要的區別:第乙個區別在於引用總是指向某個物件:定義引用時沒有初始化是錯誤的。第二個重要的區別是賦值行為的差異:給引用賦值修改的是該引用所關聯的物件的值,而並不是使引用與另乙個物件關聯。引用一經初始化,就始終指向同乙個特定的物件

1.指標的算數運算

指標的算術操作只有在原指標和計算出來的新指標都指向同乙個陣列的元素,或者指向該陣列儲存空間的下乙個單元才是合法的。

只要兩個指標指向同乙個陣列或有乙個指向該陣列末端的下乙個單元,c++支援兩個指標做減法

3. 下標和指標在使用下標訪問陣列時,實際上是對指向陣列元素的指標做下標操作。

1: int *p=&a[2];

2: int j=p[1];//實際就是a[3]

3: int k=p[-2];//實際是a[0]
const物件的指標和const指標

1.指向const物件的指標

c++強制要求指向const物件的指標也必須具有const特性

不能用void *儲存const物件的位址,而必須用const void *型別的指標儲存

允許把非const 物件的位址賦給const物件的指標

不能保證指向const的指標所指的物件的值一定不可以修改(應該稱作自以為指向const的指標)

2. cosnt 指標

const指標—本身的值不能修改

const指標必須在定義時進行初始化

3.指向cosnt物件的const 指標

const double pi=3.1415;

const double *const pi_ptr=π

既不能修改pi_ptr所指向物件的值,也不能修改該指標的指向

4.指標和typedef

假設給出下列語句

1: typedef string *pstring;
2: const pstring cstr;

cstr是const指標.宣告cosnt pstring時,cosnt修飾的是pstring型別,這是乙個指標。cstr定義為指向string型別的const指標。這個定義等同於 string *const cstr;

字串字面值就是const char型的陣列。

2.c風格字串的標準庫函式

傳遞給這些標準庫函式的指標必須具有非零值,並指向以null結束的字元陣列中的第乙個元素

1: strlen(s)      //返回s的長度,不包括字串結束符null
2: strcmp(s1,s2) //比較字串s1和s2是否相同。若相等,則返回0,;若s1大於s2返回正數,否則返回負數
3: strcat(s1,s2)     //將字串s2接到s1後,並返回s1
4: strcpy(s1,s2)   //將s2複製給s1
5: strncat(s1,s2,n)//將s2的前n個字元連線到s1後面,並返回s1
6: strncpy(s1,s2,n)   //將s2的前n個字元複製給s1,並返回s1
陣列型別的變數有三個重要的限制:陣列固定長度不變,在編譯時必須知道其長度,陣列只在定義它的塊語句內存在。

我們可以在執行時動態地分配陣列。雖然陣列長度是固定的,但動態分配的陣列不必在編譯時就知道長度,可以在執行時才確定陣列長度。與陣列變數不同,動態分配的陣列將一直存在,直到人顯示地釋放它

1.動態陣列的定義

動態分配陣列時,只需指定型別和陣列長度,不必為陣列物件命名,new表示式返回指向新分配陣列的第乙個元素的指標:

int *pia=new int[10];

new表示式需要指定指標型別和在方括號內的陣列維數,該維數可以是任何複雜的表示式。

2. 初始化動態分配的陣列

動態分配陣列時,如果陣列元素是類型別,將使用類的預設建構函式實現初始化;如果陣列元素是內建型別,則無初始化;

也可以使用在陣列長度後面的一對空圓括號,對陣列元素做值初始化

int *pia2=new int[10]();

圓括號要求編譯器做值初始化,在上面例子中,將陣列元素初始化為0

對於動態分配的陣列,其元素只能初始化為元素型別的預設值

3. const物件的動態陣列

因為陣列元素都是const物件,無法賦值。所以必須對陣列進行值初始化:

const string *p=new const string[10];//string類的預設建構函式初始化陣列元素

const int *pci=new const int[10]();

5.動態空間的釋放

c++使用delete 表示式釋放指標所指向的陣列空間:

delete pia;

該語句**了pia所指向的陣列,它告訴編譯器該指標指向的是自由儲存區中的陣列,並非單個物件。

1.混合使用標準庫類string和c風格字串

可以使用c風格字串對string物件進行初始化或者賦值

string型別的加法操作需要兩個運算元,可以使用c風格字串作為其中乙個運算元

無法用string型別初始化字元指標

但是string類提供了乙個名為c_str的成員函式,以實現我們的要求:

char *str=st2.c_str();失敗

因為c_str返回的指標指向const char型別的陣列,所以上述初始化失敗了,這樣做是為了避免修改該陣列。

const char *str=st2.c_str();成功

2. 使用陣列初始化vector物件

const size_t arr_size=6;

int int_arr[arr_size]=;

vectorivec(int_arr,int_arr+arr_size);

第二個指標指向被複製的最後乙個元素之後的位址空間。

如果表示式只提供了乙個下標,則結果獲取的元素師該行下標索引的內層陣列。如ia[3][4]陣列,ia[2]將獲得ia陣列的最後一行。

使用多維陣列名,實際上將其自動轉換為指向該陣列第乙個元素的指標

int ia[3][4];

int (*ip)[4]=ia;     ip指向含有4個元素的陣列

ip=&ia[2];            ia[2]是乙個具有4個元素的陣列

*ip是int[4]型別——即ip是乙個指向含有4個元素陣列的指標

C Primer 第四章 陣列和指標

4.2指標的引入 1.指標變數的定義 string pstring 語句把pstring定義為乙個指向string型別物件的指標變數。或者也可以如下定義 string ps 如果需要再乙個宣告語句中定義兩個指標,必須在每個變數識別符號前再加符號 宣告 string ps1,ps2 4.指標可能的取值...

C PRIMER之4 陣列和指標

1 陣列 陣列的維度必須為大於0的常量表示式 int a 3 函式體內的陣列,無初始化操作.函式體外的會初始化預設值.char b abc 會在後面新增乙個空字元.長度為4.不允許直接複製和賦值.長度是固定的.2 陣列操作 下標型別為size t 保護好避免越界 buffer overflow 3 ...

C Primer 筆記四 初識指標和引用

引用 引用是某個已存在物件的別名,實現了對其他物件的間接訪問。引用本身不是物件。其定義如下 int ival 1024 int refval ival 一般初始化變數時,初始值被拷貝到新建物件中。而定義引用時,程式把引用和它的初始值繫結在一起,一旦初始化完成,將無法把引用重新繫結到另乙個物件上,因此...