今天我們對數組與指針的知識做一個小結。包括數組、指針數組、數組指針。
一維數組與指針
在學習數組之前,必須對數組名字代表的含義非常的清楚,數組名代表的數組的首地址,通過這個首地址我們可以對這塊內存區域進行訪問,因為數組分配空間是按照順序依次分配的。
&a 與 &a+1 之間相差了幾個元素呢?
在回答這個問題之前,我們需要明白幾個知識點,我們說數組名a代表著數組的首地址,
a[i] 《==》*(a+i) 這個表達式是等價的,a+i 表示的是以內存地址a移動了i個int的地址。
我們同樣還看到了另外一個有趣的現象,a,&a[0][0],&a這三個元素打印的地址是相同的。
但是他們三個的意義卻是有很大的不同。a代表數組的首地址,在其是一維數組時,與&a[0][0]代表的意義一樣,首地址。&a代表的是把數組看成一個整體取地址&a + 1 則表示數組作為一個整體移動了一個元素(數組),其實相當于移動了5*4 = 20個字節
&a+1 - &a = 0xbfd5f6b8 - 0xbfd5f6a4 (注:當然不同類型的地址是不能相減的)
以下是利用數組名,指針變量來訪問數組元素。本地都是數組的首地址,想象一下首地址的意義。
運行結果如下:
p[i] 表示的意義就是運算式 *(p + i), 同樣的a[i] <==> *(a+i)
如果p = a時, 那么這四個表達式的值都是相等的。
二、二維數組與指針
2.1 二維數組的各個地址的含義
在二維數組中,我們又有哪些需要注意的呢?數組名代表了數組的首地址,也代表了第一行的首地址。
執行結果:
咱們通過上面的程序,可以知道的是a代表了數組的首地址,代表了第一行的首地址。記住了它這里與&a[0][0]值相等但是并沒有代表他的含義。我們可以把二維數組這么認為,把每一行當成一個整體作為一個元素,所以有咱們的a[0],a[1]正如我們初始化里面的一樣,把每行當成一個數組用{}。
分析完上述,之后我們來開始接著往下分析,它和指針之間的碰撞,看看會發生哪些意想不到的化學反應呢,記住地址是本質。
2.2 指針數組
看到指針和數組的結合,不要畏懼,我們首先來分析它的字面的意思,指針數組注意定語是數組,也就是說數組時核心,那么我們想想數組的話就會有元素的,那么比較特殊,它的元素不是我們前面學的整形、字符型。而是指針類型。也就是說元素是一個一個的地址。
執行結果:
以上三種方式情況都能訪問到我們的二維數組。那么我們來一一分析一下:
首先我們定義的指針數組,那么數組的元素只能是指針,同時我們上面進行了分析,將二維數組的每行看成是一個一維數組,那么a[0],a[1]就是每行的首地址。那么我們初始化指針數組就順理成章了。此時數組a里面就有兩個元素a[0]和a[1]。
p[0] == a[0] p[1] == a[1] ,知道每行的首地址移動j個元素,實際偏移的地址量sizeof(類型)* j個字節。那么知道了地址取出這個單元個的值,加*就ok了
我們知道帶有中括號的表達式可以這么寫p[i] == *(p + i)
2.3 數組指針
上面我們分析了指針數組,現在來分析數組指針。同樣我們來看定語是指針,那么作為指針就應該有指向了,只不過它指向的是一個數組,一個什么樣的數組呢,它指向一個包含N個元素的一維數組。原型如:int(*p)[N];
執行結果:
大家要注意的是類型的是為指針變量賦值的時候,類型要匹配
二維數組a代表著數組名,同時也是第一行的首地址,我們說把每個一維數組當成一個整體,那么我們的二維數組就成了一個一維數組了,一維數組怎么取元素的呢?a[0],a[1]…a[i] 就是這個二維數組中每一個一維數組的值,但是切記它也只是一個地址。
所以取整個數組的元素的值就有了上面的表述方式了。*(a[i] + j),*(*(a+i)+j), i表示行指針a,移動的行數,取出它的值是一行的首地址,在移動j表示在此行的基礎上移動的列數,終得到的是這個數組第i行j列的地址了,取值的話就加上*就ok了。
咱們接著來深入分析,同樣的給p變量賦值,咱們來看看還有沒有別的方式呢,數組指針,本質是一個指針,指向了一個數組,那么它里面存放的是一個地址。你可以把理解為一個二級指針。這樣也是可以的。
2.4 數組指針數組
按照咱們的上面來分析,定語是數組,那么數組就有元素,修飾語就是數組指針,那么我們可以這么認為它的本質是一個數組,數組包含了若干個元素,每個元素都是一個數組指針,也就是每一個元素是一個指針,指向了一個數組。好吧,比較拗口。依據咱們分析的意思咱們就可以寫出它的表達式了。
執行結果如下:
結束語:
關于數組與指針的結合還有很多不同種的形式,方法就是找到咱們的后的定語,和前面的修飾語,一步一步的分析,分析時刻謹記地址是本質是關鍵。