我們在學習c語言的時候, 經常會寫這樣的程式:
void func1(int *p)
void func2(int a)
int main()
即一維陣列與指標作為函式引數的互換使用, 我們可以一眼看出這個程式是可以通過編譯的.
a是陣列a[10]第乙個元素的位址, 作為引數傳遞到函式中去, 接收方是*p, 在函式中可以使用*p, 或者p[0]來訪問元素. 看起來陣列和指標可以這樣互換著使用, 編譯器會把它們編譯成一樣的東西.
問題的提出:
再來看下面的**, 為什麼這些**會報錯?
void func1(int (*p)[10])
void func2(int (*p))
void func3(int **p)
int main()
分析:
當把a作為引數傳給函式時候, a代表的是"指向陣列的指標", 該陣列一共有10個int型的元素. a本身確實是乙個指標, 但是這個指標是指向陣列的, 不是指向"陣列的首元素".
接收方也需要是此型別, int (*p)[10]表示p這個指標是指向陣列, 該陣列有10個int元素, 跟傳入引數形式一致, 因此pass.
error1和error2自然就是因為不匹配.
當把p作為引數傳給函式的時候, p代表的是"指向指標的指標", 也叫做雙重指標, 所以接收的時候int **p型別相匹配, pass.
小結:
一維陣列和指標可以互換使用, 這是由於編譯器幫我們規定了陣列名=首元素的位址, 我們才能夠這樣用.
因此不要以為二維陣列和雙重指標也可以用類似的方法來互換使用.
這當然不會是本文的最終目的. 我要說明的是, 當我們非得將**p和a這樣的形式混用時, 我們應該怎麼做.
作為引數時:
看下面的程式:
void func4(int *p)
int main()
這次我們可以將**p送給*p, 原因在於: *p表示乙個指標陣列, p就是這個指標陣列的陣列名, 也就是第乙個元素(這個元素是指標)的位址, 說白了, 就是指標的位址. 當然, 作為形式引數, p這裡就是乙個變數, 即從"位址", 變成了"指標"(變數), 所以送過來的p是雙重指標, 接收的p還是雙重指標, 當然可以編譯通過, 這又是編譯器玩的乙個花樣. 可以看出, 這個過程其實我們還是沒有擺脫上面所說的, 編譯器幫我們規定了陣列名=首元素的位址.
在函式內使用時:
看下面的程式:
#include
using namespace std;
void func1(int **c, int a, int b)
func1(p, 2, 3);
}編譯執行, 如果你像我一樣運氣好的話, 程式不會崩潰, 你會得到一組數字:
03436320
如果定義a[2][3]這樣的二維陣列, 我們在使用的時候編譯器會將a[x][y]採用形如p+3*x+y的定址方式, 因為編譯器知道我們的一行是3個元素.
在func1函式裡, 傳入的是雙重指標, 接收的是**p也是雙重指標, 可是使用的時候呢? 上面的是錯誤的示例, 因為在函式內部編譯器不知道你這個陣列是幾行幾列的.
它沒法將c[x][y]轉換成p+3*x+y的定址方式. 所以我需要同時傳入兩個額外的引數a和b來表示陣列的行列, 在使用的時候我就可以手動將c[x][y]轉換成p+a*x+y, 再加上取值符號就可以取出正確的值: *(p+a*x+y)
實際上如果你使用c[x][y]這樣的形式(如上面的程式), 編譯器不會報錯, 但是你執行的時候, 就有很大的機率崩潰, 因為編譯器將行列錯誤的進行了解析.
這時編譯器是這樣編譯的:
它取出c[x]作為行的首位址, 再加上y.
由於c[0]一定是傳入陣列的首位址, 所以c[0][y]這樣的訪問都是ok的, 只要你不越界.
c[1]我們就不知道是個什麼東西了, c[1][y]這樣的訪問就是乙個隨機數, 當訪問到無法訪問的地方時, 程式就會崩潰.
最後的總結:
1. 一維陣列和指標可以比較簡單的互換使用
2. 二維陣列和雙重指標盡量不要互換使用, 除非你真的知道這些底層的編譯原理, 並且有十分的把握
二維陣列 二維陣列和指標
include using namespace std int main 如上面這段程式所示,通過取位址符 指標 p 獲得了變數 a 的位址,那麼解引用符 就可以從 p 中得到變數 a 的值。也就是說,p a和 p a是等價的。p 是變數 a 的位址,從 p 中就可以取出 a 的值。反之,能從 p ...
c 二維陣列賦值及二維指標使用
include void main int tmp 2 test printf value d n tmp 0 printf value d n tmp 0 printf value d n tmp 1 printf value d n tmp 1 printf value d n tmp 0 1 ...
二維陣列及指標
乙個陣列的元素值為指標則是指標陣列。指標陣列的所有元素都必須是具有相同儲存型別和指向相同資料型別的指標變數。指標陣列說明的一般形式為 型別說明符 陣列名 陣列長度 其中型別說明符為指標值所指向的變數的型別。例如 int pa 3 表示pa 是乙個指標陣列,它有三個陣列元素,每個元素值都是乙個指標,指...