《C和指標》讀書筆記 7

2021-06-15 02:17:12 字數 3044 閱讀 6122

宣告:該讀書筆記摘抄自《c和指標》——kenneth a.reek (著)    徐波(譯)。為了克服自己走馬觀花,提高閱讀和學習效率,決定將自己在讀書過程中遇到的一些知識點加以摘抄和總結備忘,在此感謝原書作者和翻譯。

一、陣列名

1、乙個誤區:陣列名並不表示整個陣列,它大多時候只是乙個指標常量,指向陣列的第乙個元素,它的型別取決於陣列元素型別。這一點解釋了為什麼c語言的陣列不能整體拷貝,只能迴圈拷貝賦值。如果你將陣列名賦值給另乙個陣列名,例如,int  a[10] ;  intb[10];  a = b; ,就已經錯的一塌糊塗:

1)陣列名是乙個常量指標,它不可以被賦值;

2)就是上面提到的陣列不能整體拷貝,因為你得到的僅僅是乙個指向陣列第乙個元素的指標常量而已。

注:個人認為這兩點其實本質上是乙個意思。即,假如陣列名不是乙個指標常量而是表示整個陣列,那麼它可以整體賦值。

2、陣列名大多時候是乙個常量指標,但是有且只有兩種情況,陣列名不用指標常量來表示:

1)作為sizeof的表示式的時候,陣列名表示整個陣列,sizeof會返回整個陣列占用的位元組數;

2)當陣列名作為操作符&的運算元時,會產生乙個指向該陣列的指標。

二、陣列的下標引用

1、當用下標來訪問陣列時,下標值可以為任意整數值,可以為負,但是程式設計師自己必須保證訪問的有效性,即不能跳出陣列的前邊界;下標值也可以大於陣列實際長度,這通常用來實現不對稱邊界,但是要避免對超出陣列有效長度的位址進行訪問(只要位址,不要值)。

2、c語言並不會對陣列下標有效性進行安全檢查,c語言標準也並沒有規定編譯器必須對陣列下標進行有效性檢查,對陣列下標的有效性檢查會大大增加程式執行時間和空間的開銷。也就是說保證陣列訪問不越界的工作應該交由程式設計師來做。

3、a[2] 和2[a] 都是合法的,並且具有相同的效果,這緣於c語言實現下標的方式,因為在c語言中對下標的訪問都可以轉換為對等的間接訪問表示式。a[2] 、2[a]都會被編譯器轉換為*(2 + a),這兩種下標書寫形式對編譯器來說並無差異。當然,如果你不是在參加混亂**大賽,在**可讀性上沒有人會喜歡2[a]這種書寫方式。

三、指標與下標

1、加入下標和指標都可以實現某種需要,下標一定不會比指標更有效率,並且有時候指標比下標更有效率。

2、指標比下標更有效率的場合:當在陣列中迴圈變數一次以固定步長移動時,固定數字與固定數字的相乘是在編譯期間完成的,不會占用執行時間,更有效率一些。

3、乙個高效率的陣列的拷貝, 將陣列y的元素賦給陣列x

#define      size             10

int    x[size], y[size] ;

void array_to_array(void) }

四、陣列和指標

1、陣列和指標都具有指標值,都可以進行間接訪問和下標引用操作,但是需要注意的是他們並不等價。宣告乙個陣列時,編譯器首先根據陣列元素個數為該陣列分配記憶體,然後再建立陣列名,它是乙個指標常量,指向陣列的第乙個元素。宣告乙個指標變數時,編譯器只為該變數分配4個位元組的記憶體。

2、當乙個陣列名作為引數傳遞給乙個函式時,該陣列名退化為指標,此時,在函式內部對其sizeof時,得到的結果是4(32位機器),

3、編譯器允許陣列不完整初始化,但只允許順序省略後面的初始值,被省略的初始值全部為0;例如,int   a[10] = ;   a[0] = 1, a[1] = 2, a[2]~a[9]全部為0。另外,對於全域性陣列,預設初始值都是0, 但是如果對於乙個區域性陣列,並且所有元素都沒有初始化時,其所有元素初始值都是不確定的。

4、在陣列宣告時,允許編譯器自動計算陣列長度,例如,int   a[ ] = ;

5、字元陣列的初始化,

方法1、char    a[ ] = ;        只適用於較短的字元陣列初始化

方法2、char    a[ ] = "hello";   注意這種初始化方法與字串常量的區別:當它用於初始化乙個字元陣列時,它就是乙個字元陣列的初始化列表,其他的任何情況都是字串常量。

五、多維陣列

1、int     a[3][4]; 可以將a看作乙個具有三個元素的一維陣列,只不過每個元素又是乙個具有4個元素的一位陣列;

同樣,int     a[2][3][4];將a看作乙個具有兩個元素的一維陣列,其中每個元素又是乙個具有三個元素的一維陣列,而這三個元素的每乙個又是乙個具有4個元素的一維陣列。可見,多維陣列可以看作是很多一維陣列的巢狀集合。

2、多維陣列在記憶體中的儲存順序

在c語言中,多維陣列元素的儲存順序按照最右邊的下標率先變化,這稱為行主序。

3、指向陣列的指標

例如:int  a[3][4], *(p)[4] = a; 此時p指向該二維陣列的第一行,p+1指向第二行,每一行是乙個具有4個元素的陣列,此時p就是乙個指向陣列的指標。

特別注意:若p初始化為int  *p = a; 則是錯的,因為p是乙個指向整型的指標,而二維陣列名a是乙個指向二維陣列第一行的一維陣列的指標常量,也就是說a是乙個指向陣列的指標,相當於二級指標,用乙個二級指標初始化乙個一級指標,顯然不合適。此時應該使用行指標變數,即int   (*p)[4]才正確,要注意,除了第一維宣告為指標p外,其他各維必須明確用下標指定。 若將行指標變數定義為int   (*p)[ ]; 此時p仍然是乙個指向乙個一維陣列的行指標變數,但是此時一維陣列的長度卻沒有指定,於是當p指標參與運算時,它指向的陣列將會被視為空陣列,即陣列長度為0,計算指標p的步長時將與0相乘,這種情況可能不是你想要的,應該避免。

4、多維陣列作為函式引數

例如有乙個二維陣列:  int  a[3][4];    

a作為引數傳遞給函式:      func(a);

函式func的宣告形式為: void func(int  p[ ][4])   或者void func(int   (*p)[4])

注:要區別void  func(int   **p) ,這種宣告形式是錯誤的,p是乙個真正的二級指標,即p被宣告為乙個指向整型的指標的指標。

5、多維陣列的初始化

原則:按照最右邊的下表率來變化。

6、多維陣列的長度自動計算

注意,在多維陣列中只有第一維的長度才能自動計算,其餘各維必須顯示指定。

七、指標陣列

下表優先順序高於間接訪問符優先順序

以上為第八章「陣列和指標」摘抄總結,未完待續。。。

C和C指標讀書筆記

1.c中變數的儲存型別 儲存型別分為靜態儲存 普通記憶體 堆疊,暫存器自動變數即 塊內部的變數儲存於堆疊,其他變數儲存於普通記憶體即靜態儲存,如果頻繁訪問乙個變數,宣告為暫存器型別後儲存於硬體暫存器中。2.c中實體的鏈結屬性 1 屬於internal鏈結屬性的識別符號在同乙個原始檔內的所有宣告中都指...

C和指標讀書筆記 第7章(函式)

1.把函式的型別與函式名分寫成兩行純屬風格問題。這種寫法可以使我們在使用視覺或者某些工具追蹤 時更容易查詢程式。2.ruturn 語法並沒有要求你加上括號。3.向編譯器提供函式資訊的方法是使用函式原型。原型總結了函式定義的起始部分的宣告,向編譯器提供有關該函式應該如何呼叫的完整資訊。在函式原型後面要...

《C和指標》讀書筆記 6

宣告 該讀書筆記摘抄自 c和指標 kenneth a.reek 著 徐波 譯 為了克服自己走馬觀花,提高閱讀和學習效率,決定將自己在讀書過程中遇到的一些知識點加以摘抄和總結備忘,在此感謝原書作者和翻譯。一 遞迴的兩個特性 1 存在限制條件 2 每次遞迴之後越來越接近限制條件 二 將二進位制數字轉換為...