一維陣列使用陣列名稱與一個索引值來指定存取陣列元素,二維陣列使用陣列名稱與兩個索引值來指定存取陣列元素,宣告方式與一維陣列類似:
int maze[5][10];
上面這個宣告會配置 5 * 10 = 50 個整數的記憶體空間給陣列來使用,二維陣列使用兩個索引值來指定存取陣列,這兩個索引值都是由 0 開始,下面這個程式簡單的示範二維陣列的存取:
#include <stdio.h>
#define ROW 5
#define COLUMN 10
int main(void) {
int maze[ROW][COLUMN];
for(int i = 0; i < ROW; i++) {
for(int j = 0; j < COLUMN; j++) {
maze[i][j] = (i + 1) * (j + 1);
}
}
for(int i = 0; i < ROW; i++) {
for(int j = 0; j < COLUMN; j++) {
printf("%d\t", maze[i][j]);
}
putchar('\n');
}
return 0;
}
執行結果:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
在上面這個程式中,宣告了 5 列(Row)、10 行(Column)的陣列,第一個 []
是用來指定存取哪一列,第二個 []
是用來指定存取哪一行,所以使用 maze[i][j]
時,表示要存取 i
列 j
行的元素。
也可以在宣告二維陣列的同時指定二維陣列的值,例如:
int maze[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
從上面這個程式來看,可以清楚地看出 maze[2][3]
中 2 與 3 的意義,maze[2]
表示 maze
有兩個元素,各是 {1, 2, 3}
與 {4, 5, 6}
,也就是說,這兩個元素是一維陣列,而長度是 3。
若清楚二維陣列的記憶體配置方式,會理解到 {}
其實是可以不用的,例如:
int maze[2][3] = {
1, 2, 3,
4, 5, 6
};
何謂二維陣列於記憶體中的配置方式?其實陣列存取時的行與列,是為了理解陣列元素的指定存取而想像出來的,索引值正確的意義,是指相對於陣列第一個元素 的位移量,例如在一維陣列中的陣列配置與索引意義如下圖所示:
對 int
整數陣列來說,每一位移量是 4 個位元組,而指定存取 maze[4]
,相當於指定存取相對於 maze[0]
四個位移量的記憶體空間。
即使是二維空間,其在記憶體中也是線性配置的,例如:
在上面的例子中,二維陣列將得到的記憶體分為兩個區塊,我們宣告陣列 maze[2[4]
,表示 maze[0][0]
與 maze[1][0]
相對位移量為 4,當指定存取 maze[1][3]
時,表示存取的位置是相對於 maze[1][0]
位移 3 個單位。
若宣告 maze[3][5]
的話,記憶體位置的指定是如何呢?在這個陣列中 5 的意義是 maze[0][0]
、maze[1][0]
與 maze[2][0]
的位置各相對 5 個位移量,如下圖所示:
瞭解二維陣列在記憶體中的配置關係後,就可以知道,上圖可以看成是三個一維陣列在記憶體中連續配置,嚴格來說,C 沒有二維陣列這種東西,二維或多維陣列的概念,是以陣列的陣列(arrays of arrays)來實現。
可以使用底下的程式來驗證所謂的二維陣列,就是具有兩個一維陣列作為元素的陣列:
#include <stdio.h>
#define ROWS 2
#define LEN 3
int main(void) {
int maze[ROWS][LEN] = {
{1, 2, 3},
{4, 5, 6}
};
for(int i = 0; i < ROWS; i++) {
int *row = maze[i];
for(int j = 0; j < LEN; j++) {
printf("%d\t", row[j]);
}
printf("\n");
}
}
就目前來說,可以知道的是 maze[i]
為每個一維 int
陣列的位址,型態是 int*
,這是指標型態,之後會談到,也就是說 row
代表了每個一維 int
陣列,因而內層 for
迴圈可以使用索引來取得一維陣列內容。
更多維的陣列,就是依以上說明類推罷了,例如三維陣列:
int arr[2][4][6];