二維陣列的詳解

2021-08-21 17:11:27 字數 3211 閱讀 3104

二維陣列在概念上是二維的,有行和列,但在記憶體中所有的陣列元素都是連續排列的,它們之間沒有「縫隙」。

要用陣列指標來操作二維陣列。int (*p)[4]=a;  //p每移動一次就是移動了乙個一維陣列。

指標陣列:int *p=a[4];

int *p([4]);

以下面的二維陣列 a 為例:

int a[3][4] = , , };

從概念上理解,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 的指標變數 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 行。?

#include

intmain(), , };

int(*p)[4] = a;

printf("%d\n",sizeof(*(p+1)));

return0;

}

執行結果:

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

intmain();

int(*p)[4];

inti,j;

p=a;

for(i=0; i<3; i++)

return0;

}

執行結果:

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 個位元組的記憶體。

例二:二維陣列就是幾個拆開的一維陣列,a[0]是第乙個一維陣列,a[2]是第二個一維陣列。

#include

#define m 2

#define n 10

int main()

for(i = 0; i < m; i++)

return 0;

}結果:

farsight@ubuntu:~/c$ ./a.out

abc    //輸入的第乙個一維陣列

def     //輸入的第二個一維陣列

abc   //輸出的第乙個一維陣列

def    //輸出的第二個一維陣列

farsight@ubuntu:~/c$ ^c

二維陣列詳解

問題 cannot convert from double 10 10 to double 例如 double arry 5 10 double pp pp arry 直接的賦值會提示錯誤 cannot convert from double 10 10 to double 解決方法 double ...

詳解二維陣列

一 定義 int arr 3 int brr 3 4 對比一位陣列,二維陣列具有行和列兩個引數,在定義上,與一維陣列相似 資料型別 陣列名 行 列 二 初始化 同樣,對於一維陣列的初始化,如下所示 int arr 3 int arr 3 其餘預設為0 那麼,二維陣列呢?二維陣列的初始化採用行優先的原...

Objective C 二維陣列詳解

在實際的專案開發中,二維陣列也是常常用到的資料結構。oc中的二維陣列也是通過一維陣列來建立的,今天我們來詳解一下如何在oc中使用二維陣列。使用nsarray初始化二維陣列 使用nsarray初始化的一維陣列和二維陣列都是不可變陣列。import int main int argc,const cha...