一、陣列名
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)
register int *p1, *p2;
for (p1=x, p2=y; p1<&x[size]; ) ; 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、多維陣列的長度自動計算
注意,在多維陣列中只有第一維的長度才能自動計算,其餘各維必須顯示指定。
《c和指標》之總結 三
5 操作符和表示式 操作符優先順序 操作符 描述 用法示例 結果型別 結合型 是否控制求值順序 聚組 表示式 與表示式同 n a否 函式呼叫 rexp rexp,rexp l r否 下標引用 rexp rexp lexp l r否 訪問結構體成員 lexp.member name lexp l r否...
《C和指標》讀書筆記(三)
c語言沒有bool型別,所以只能用0代表假,非0代表真 盡量少用goto語句,能不弄則不用,goto語句只在一種情況下比較好,就是跳出多層巢狀迴圈時。算術操作運算子 只接受整形 左移 全部補零 右移 邏輯移位 補零 算數移位 根據符號位 計算乙個值中1的個數 最初版 include using na...
C 類和物件(三) C 物件模型和this指標
c 中,類的成員變數和成員函式分開儲存。只有非靜態成員變數屬於類的物件,占用物件的記憶體空間。注1 非靜態成員函式和靜態成員 包括靜態成員變數與靜態成員函式 均不屬於類的物件,不占用物件的記憶體空間。注2 非靜態成員函式並非某個物件獨有,記憶體中僅存在乙份資料 乙份函式例項 不同物件的某個非靜態成員...