C語言 指標與二維數組詳解_C 語言

來源:互聯網
上載者:User

二維數組在概念上是二維的,有行和列,但在記憶體中所有的數組元素都是連續排列的,它們之間沒有“縫隙”。以下面的二維數組 a 為例:

int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };

從概念上理解,a 的分布像一個矩陣:

0   1   2   3
4   5   6   7
8   9  10  11

但在記憶體中,a 的分布是一維線性,整個數組佔用一塊連續的記憶體:

C語言中的二維數組是按行排列的,也就是先存放 a[0] 行,再存放 a[1] 行,最後存放 a[2] 行;每行中的 4 個元素也是依次存放。數組 a 為 int 類型,每個元素佔用 4 個位元組,整個數組共佔用 4×(3×4) = 48 個位元組。

C語言允許把一個二維數組分解成多個一維數組來處理。對於數組 a,它可以分解成三個一維數組,即 a[0]、a[1]、a[2]。每一個一維數組又包含了 4 個元素,例如 a[0] 包含 a[0][0]、a[0][1]、a[0][2]、a[0][3]。

假設數組 a 中第 0 個元素的地址為 1000,那麼每個一維數組的首地址如下圖所示:

為了更好的理解指標和二維數組的關係,我們先來定義一個指向 a 的指標變數 p:

int (*p)[4] = a;

括弧中的*表明 p 是一個指標,它指向一個數組,數組的類型為int [4],這正是 a 所包含的每個一維數組的類型。

[ ]的優先順序高於*,( )是必須要加的,如果赤裸裸地寫作int *p[4],那麼應該理解為int *(p[4]),p 就成了一個指標數組,而不是二維數組指標,這在《C語言指標數組》中已經講到。

對指標進行加法(減法)運算時,它前進(後退)的步長與它指向的資料類型有關,p 指向的資料類型是int [4],那麼p+1就前進 4×4 = 16 個位元組,p-1就後退 16 個位元組,這正好是數組 a 所包含的每個一維數組的長度。也就是說,p+1會使得指標指向二維數組的下一行,p-1會使得指標指向數組的上一行。

數組名 a 在運算式中也會被轉換為和 p 等價的指標!

下面我們就來探索一下如何使用指標 p 來訪問二維數組中的每個元素。按照上面的定義:

1) p指向數組 a 的開頭,也即第 0 行;p+1前進一行,指向第 1 行。

2) *(p+1)表示取地址上的資料,也就是整個第 1 行資料。注意是一行資料,是多個資料,不是第 1 行中的第 0 個元素,下面的運行結果有力地證明了這一點:

#include <stdio.h>int main(){ int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} }; int (*p)[4] = a; printf("%d\n", sizeof(*(p+1))); return 0;}

運行結果:

16

3) *(p+1)+1表示第 1 行第 1 個元素的地址。如何理解呢?

*(p+1)單獨使用時表示的是第 1 行資料,放在運算式中會被轉換為第 1 行資料的首地址,也就是第 1 行第 0 個元素的地址,因為使用整行資料沒有實際的含義,編譯器遇到這種情況都會轉換為指向該行第 0 個元素的指標;就像一維數組的名字,在定義時或者和 sizeof、& 一起使用時才表示整個數組,出現在運算式中就會被轉換為指向數組第 0 個元素的指標。

4) *(*(p+1)+1)表示第 1 行第 1 個元素的值。很明顯,增加一個 * 表示取地址上的資料。

根據上面的結論,可以很容易推出以下的等價關係:

a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)

【執行個體】使用指標遍曆二維數組。

#include <stdio.h>int main(){ int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; int(*p)[4]; int i,j; p=a; for(i=0; i<3; i++){  for(j=0; j<4; j++) printf("%2d ",*(*(p+i)+j));  printf("\n"); } return 0;}

運行結果:

0   1   2   3
 4   5   6   7
 8   9  10  11

指標數組和二維數組指標的區別

指標數組和二維數組指標在定義時非常相似,只是括弧的位置不同:

int *(p1[5]);  //指標數組,可以去掉括弧直接寫作 int *p1[5];
int (*p2)[5];  //二維數組指標,不能去掉括弧

指標數組和二維數組指標有著本質上的區別:指標數組是一個數組,只是每個元素儲存的都是指標,以上面的 p1 為例,在32位環境下它佔用 4×5 = 20 個位元組的記憶體。二維數組指標是一個指標,它指向一個二維數組,以上面的 p2 為例,它佔用 4 個位元組的記憶體。

以上就是C語言 指標和二維數組的資料整理,後續繼續補充相關知識,謝謝大家對本站的支援!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.