當前位置:才華齋>計算機>C語言>

C語言指標和陣列的學習方法

C語言 閱讀(1.44W)

C語言中的指標和陣列一直是讓自己覺得頭疼的問題,最近好好研究了一下,將自己的體會寫下來,當做總結吧。

C語言指標和陣列的學習方法

C語言指標和陣列的學習方法

先說指標,首先指標是一個變數,但它存的是變數的地址,利用指標可以間接訪問一個變數,比如下面這個例子:

int a;

int *p=&a;

定義了一個整型變數a,定義了一個指向整型變數的指標變數p,這時候指標變數p裡面存的就是整型變數a的地址。在後面要為a賦值的時候,比如賦值為10,可以這樣寫:a=10;也可以這樣寫:*p=10;這兩個表示式都是等價的,也就是說,可以通過*這個符號,去訪問某個地址的內容。我覺得之前看過的一個比喻非常好(具體出處忘了),說*這個符號就像一把鑰匙,而指標變數就像一把鎖,拿*這把鑰匙把指標變數這把鎖開啟,然後就能往開啟後的這個空間裡面存放東西。我覺得指標這個東西很神奇,因為它能指向不同的變數,即不同的空間。

再來說陣列,陣列最頭疼的就是陣列名,但陣列名的定義已經很明確了,陣列名是指向陣列首元素的指標常量,這個定義簡直就是一針見血,來看一些例子:

1.

int n[10] ;

定義了一個有10個元素的整型陣列n,那麼根據定義,陣列名n和&n[0]是等價的,如果我們這樣操作:n+1,那麼n+1就和&n[1]是等價的,因為這裡的n是一個指向整型變數的指標常量,這裡n的型別很重要。

2.

int n[10][10];

定義了一個有100個元素的二維整型陣列n,那麼n是否和&n[0][0]是等價的呢?答案是否定的。當我們定義了n[10][10]這個二維陣列時,編譯器“咔嚓”、“咔嚓”將一段記憶體空間剪成10份,然後又“咔嚓”、“咔嚓”將每一份空間再剪成10份,然後便得到了100個最小空間為一個int型大小的空間,那麼n代表什麼呢?陣列名的定義:陣列名是指向陣列首元素的指標常量,這裡n代表指向上面編譯器第一次將記憶體“咔嚓”、“咔嚓”剪成10份的首元素(裡面包含10個int型)的指標常量,這就是n的型別,很明顯,n的型別不是一個指向int型別的指標變數,所以n和&n[0][0]並不等價。這時我們如果這樣操作:n+1,那麼n+1便指向了上面編譯器“咔嚓”的第二段,寫到這你會想,既然n和&n[0][0]並不等價,那麼n和&n[0]是否等價呢?答案是對的。多維陣列有個很特殊的地方,因為它還有這樣的陣列名:n[0],這個代表什麼呢?答案就是n[0]才是和&n[0][0]等價的`。所以最後得出的結論是:*n[0]代表n[0][0],*n代表n[0],**n代表n[0][0],這種感覺就像,沒開鎖的時候(n),在你面前放著的是整個大寶箱(整個陣列n[10][10])裡面的第一個大寶箱,裡面裝著10個小寶箱(n[0]),當你第一次把鎖開啟(*n),你面前放著的是10個小寶箱裡面的第一個小寶箱,當然你也可以選擇第二個(*n+1),你再一次把鎖開啟(**n),就能看見寶石啦!

更多維的陣列也可以這樣分析。

為了驗證上面的說法,在C編譯器裡面輸入下面的程式碼:

#include "stdio.h"

main()

{

int n[2][2] = {1, 2, 3, 4};

printf("n[0][0] is %d", n[0][0]);

printf("*n[0] is %d", *n[0]);

printf("**n is %d", **n);

printf("*(*n+1) is %d", *(*n+1));

printf("**(n+1) is %d", **(n+1));

printf("n[0] is %d", n[0]);

printf("*n[0] is %d", *n[0]);

printf("n is %d", n);

printf("*n is %d", *n);

}

執行結果是:

執行結果和上面分析的一致。但,這裡有個問題是,既然n[0]和n的結果是一樣的,那為什麼*n[0]和*n的結果不一樣呢?原因是型別不一致,*n[0]直接就把小寶箱打開了,但*n才剛開啟上一層呢。但C語言提供了穿越的方法,這樣:*(int *)n,把n直接強制轉換成一個指向int型別的指標,然後用*開啟,便取得了寶石,太神奇了!