《C專家程式設計》的筆記 指標與陣列的區別

2021-06-22 00:37:37 字數 1364 閱讀 6440

在很多人眼裡,c語言的指標和陣列是等價的。幾乎在任何時候陣列都可以指標來替換,這使得很多人把這兩個型別視作等價。其實完全不同。陣列中存的是資料,指標中存的是位址。我們造成這樣的誤解是有情可緣的,對於int *a而言,a是乙個變數,這個變數的值是乙個4位元組整數的位址。而對於int a[10]而言,我們常常可以在一些書上看到a指向陣列的第乙個元素,似乎它也是個指標變數,變數的值是a[0]的位址。這與int *a似乎完全一樣。但其實不然:看下面一段程式:

int a[

10];

intmain

()

翻譯出的彙編可以看到

movl $4, -24(%ebp)

對於乙個陣列char a[10]而言,如果訪問a[i],步驟是:

1. 將a的位址讀入暫存器,由於a其實就是乙個別名,所以a的位址本身就是a[0]的位址

2. 根據型別計算並新增偏移,得到目標位址

3. 訪問記憶體得到a[i]

而如果宣告是char *a,訪問a[i],其步驟是:

1. 將a的位址讀入暫存器,a是乙個指標,指向a[0]的位址。

2. 訪問記憶體讀取a的值,得到a[0]的位址。

3. 根據型別計算並新增偏移量,得到目標位址

4. 訪問記憶體得到a[i]

根據這樣的理解,當我們在乙個檔案中宣告變數為char *a,而在另乙個檔案中將a定義為陣列,即char a[10],將會造成非常大的問題。在宣告變數的檔案中使用a[i],將首先會把a的位址讀入暫存器,訪問記憶體取出a的值,而由於其定義為陣列,因此a的位址就是a[0]的位址,將取出的a[0]作為目標位址的基址顯然是錯誤的。

那麼肯定有人會問,int *p = a算是個什麼東西,不是說好的a是個別名而已麼,a的位址才是a[0]的位址啊。其原因是,c標準中說道,在表示式中使用陣列,編譯器會將陣列自動轉化成指標,這是所有c編譯器必須有的行為,該指標指向陣列的第乙個元素。

需要注意的是,

對於指標的下標操作,當且僅當其定義是陣列的時候才有效,對於指標型別的宣告,編譯器將下標操作直接作為加號操作,因此a[5]和5[a]在a為指標的時候都是合法的。

可能又會有人有疑問,常常看到一些函式的簽名是指標,可傳入的是陣列,不也沒事兒麼。

c標準還有一條:當陣列出現在函式的引數中時,無論是形參還是實參,都轉換為指標再進行操作。

因此main函式的引數char *argv,也可以寫成char **argv.

但這種轉換不是在任何時候都成立的,比如多維陣列的情形,char a[3][4][5]作為引數傳遞的時候只會轉換為乙個3維陣列的指標char (*a)[4][5],而不會轉成指標的指標的指標。

函式不可以返回陣列,但可以返回陣列的指標,比如:

int

(*func

())

指標和陣列 C專家程式設計筆記

對於編譯器而言,乙個陣列就是乙個位址,乙個指標就是乙個位址的位址。什麼時候陣列和指標是相同的 1 表示式中的陣列名 與宣告不同 被編譯器當作乙個指向該陣列第乙個元素的指標 在表示式中,指標和陣列是可以互換的,因為它們在編譯器裡的最終形式都是指標,並且都可以去下標操作.例對陣列的引用如a i 在編譯時...

《C專家程式設計》讀書筆記之 指標與陣列

陣列並非指標 c初學者都會認為陣列與指標是相同的,的確在很多情況下是可以這樣認為,但是這是有條件的 先看下面宣告 int a 100 然後在引用 extern int a 然後程式會報錯。讓我們先了解宣告和定義的區別 1.宣告相當於普通的宣告 它所說的並非自身,而是描述其他地方建立的物件,可以出現多...

C語言筆記 指標 指標與陣列

和 可以將指標向前或向後移動 n 個位元組,n 取決於指標的型別在此計算機中占用的位元組數,使用的方法和普通變數一樣。兩個指標相減則可以得到兩指標間的距離,這種運算只有在兩個指標指向同乙個陣列中的元素時候有意義,可以計算出兩個指標指向的元素之間相隔多少個元素 指標也可以使用 等運算子進行比較,但也是...