指標變數可以指向一維陣列中的元素,當然也就可以指向二維陣列中的元素。但是在概念和使用方法上,二維陣列的指標比一維陣列的指標要複雜一些。要理解指標和二維陣列的關係首先要記住一句話:二維陣列就是一維陣列,這句話該怎麼理解呢?
假如有乙個二維陣列:
int a[3][4] = , , };其中,a 是二維陣列名。a 陣列包含 3 行,即 3 個行元素:a[0],a[1],a[2]。每個行元素都可以看成含有 4 個元素的一維陣列。而且 c 語言規定,a[0]、a[1]、a[2]分別是這三個一維陣列的陣列名。如下所示:
a[0]、a[1]、a[2] 既然是一維陣列名,一維陣列的陣列名表示的就是陣列第乙個元素的位址,所以 a[0] 表示的就是元素 a[0][0] 的位址,即 a[0] == &a[0][0];a[1] 表示的就是元素 a[1][0] 的位址,即 a[1] == &a[1][0];a[2] 表示的就是元素 a[2][0] 的位址,即 a[2] == &a[2][0]。
a[i] == &a[i][0]我們知道,在一維陣列 b 中,陣列名 b 代表陣列的首位址,即陣列第乙個元素的位址,b+1 代表陣列第二個元素的位址,…,b+n 代表陣列第 n+1 個元素的位址。所以既然 a[0]、a[1]、a[2]、…、a[m–1] 分別表示二維陣列 a[m][n] 第 0 行、第 1 行、第 2 行、…、第 m–1 行各一維陣列的首位址,那麼同樣的道理,a[0]+1 就表示元素 a[0][1] 的位址,a[0]+2 就表示元素 a[0][2] 的位址,a[1]+1 就表示元素 a[1][1] 的位址,a[1]+2 就表示元素 a[1][2] 的位址……a[i]+j 就表示 a[i][j] 的位址,即(式二):
a[i]+j == &a[i][j]將式一代入式二得(式三):
&a[i][0]+j == &a[i][j]在一維陣列中 a[i] 和 *(a+i) 等價,即(式四):
a[i] == *(a+i)(13-4)這個關係在二維陣列中同樣適用,二維陣列 a[m][n] 就是有 m 個元素 a[0]、a[1]、…、a[m–1] 的一維陣列。將式四代入式二得(式五):
*(a+i)+j == &a[i][j]由式二和式五可知,a[i]+j 和 *(a+i)+j 等價,都表示元素 a[i][j] 的位址。
上面幾個公式很「繞」,理清楚了也很簡單,關鍵是把式二和式五記住。
下面來**乙個問題:「二維陣列 a[m][n] 的陣列名 a 表示的是誰的位址?」在一維陣列中,陣列名表示的是陣列第乙個元素的位址,那麼二維陣列呢? a 表示的是元素 a[0][0] 的位址嗎?不是!我們說過,二維陣列就是一維陣列,二維陣列 a[3][4] 就是有三個元素 a[0]、a[1]、a[2] 的一維陣列,所以陣列 a 的第乙個元素不是 a[0][0],而是 a[0],所以陣列名 a 表示的不是元素 a[0][0] 的位址,而是 a[0] 的位址,即:
a == &a[0]
a[0] == &a[0][0]所以二維陣列名 a 和元素 a[0][0] 的關係是:
a == &(&a[0][0])
int *p;並希望這個指標變數指向二維陣列 a,那麼不能把 a 賦給 p,因為它們的型別不一樣。要麼把 &a[0][0] 賦給 p,要麼把 a[0] 賦給 p,要麼把 *a 賦給 p。前兩個好理解,可為什麼可以把 *a 賦給 p?因為 a==&(&a[0][0]),所以 a==(&(&a[0][0]))==&a[0][0]。
除此之外你也可以把指標變數 p 定義成 int(*)[n] 型,這時就可以把 a 賦給 p,而且用這種方法的人還比較多,但我不喜歡,因為我覺得這樣定義看起來很彆扭。
如果將二維陣列名 a 賦給指標變數 p,則有(式六):
p == a那麼此時如何用 p 指向元素 a[i][j]?答案是以「行」為單位進行訪問。陣列名 a 代表第乙個元素 a[0] 的位址,則 a+1 就代表元素 a[1] 的位址,即a+1==&a[1];a+2 就代表 a[2] 的位址,即 a+2==&a[2]……a+i 就代表 a[i] 的位址,即(式七):
a+i == &a[i]將式六代入式七得:
p+i == &a[i]等式兩邊作「*」運算得:
*(p+i) == a[i]等式兩邊同時加上j行(式八):
*(p+i) + j == &a[i][j]式八就是把二維陣列名 a 賦給指標變數 p 時,p 訪問二維陣列元素的公式。使用時,必須先把 p 定義成 int()[n] 型,然後才能把二維陣列名 a 賦給 p。那麼怎麼把 p 定義成 int()[n] 型呢?關鍵是 p 放什麼位置!形式如下:
>
int(
*p)[n]
= a;
/*其中n是二維陣列a[m][n]的列數, 是乙個數字, 前面說過, 陣列長度不能定義成變數*/
下面編乙個程式來用一下:
# include
intmain
(void);
int i, j;
int(
*p)[4]
= a;
//記住這種定義格式
for(i=
0; i<3;
++i)
printf
("\n");
}return0;
}
輸出結果是:
123
4567
891011
12
如果把 &a[0][0] 賦給指標變數 p 的話,那麼如何用 p 指向元素 a[i][j] 呢?在前面講過,對於記憶體而言,並不存在多維陣列,因為記憶體是一維的,記憶體裡面不分行也不分列,元素都是按順序乙個乙個往後排的,所以二維陣列中的每乙個元素在記憶體中的位址都是連續的,寫乙個程式來驗證一下:
# include
intmain
(void);
int i, j;
for(i=
0; i<3;
++i)
printf
("\n");
}return0;
}
輸出結果是:
0x18ff18
0x18ff1c
0x18ff20
0x18ff24
0x18ff28
0x18ff2c
0x18ff30
0x18ff34
0x18ff38
0x18ff3c
0x18ff40
0x18ff44
p == &a[0][0]; p + 1 == &a[0][1]; p + 2 == &a[0][2]; p + 3 ==如果仔細觀察就會發現有如下規律:&a[0][3]; p + 4 == &a[1][0]; p + 5 == &a[1][1]; p + 6 == &a[1][2];
p + 7 == &a[1][3]; p + 8 == &a[2][0]; p + 9 == &a[2][1]; p + 10
== &a[2][2]; p + 10 == &a[2][3];
p+i*4+j == &a[i][j]其中 4 是二維陣列的列數。
所以對於二維陣列 a[m][n],如果將 &a[0][0] 賦給指標變數 p 的話,那麼 p 訪問二維陣列元素 a[i][j] 的公式就是:
p + i*n +j == &a[i][j]下面把驗證式八的程式修改一下,驗證一下上式:
# include
intmain
(void);
int i, j;
int*p =
&a[0][
0];//把a[0][0]的位址賦給指標變數p
for(i=
0; i<3;
++i)
printf
("\n");
}return0;
}
輸出結果是:
123
4567
891011
12
結果是一樣的。兩種方法相比,第二種方法更容易接受,因為把 &a[0][0] 賦給指標變數 p 理解起來更容易,而且 p 定義成 int* 型從心理上或從感覺上都更容易接受。 C語言二維陣列指標(指向二維陣列的指標)
二維陣列的定義 int matrix 見圖的操作那篇文章裡面的定義 或者這篇文章提供了另外一種方法。二維陣列在概念上是二維的,有行和列,但在記憶體中所有的陣列元素都是連續排列的,它們之間沒有 縫隙 以下面的二維陣列 a 為例 int a 3 4 從概念上理解,a 的分布像乙個矩陣 0 1 2 3 4...
二維陣列的指標表示
1.型別說明 int b 定義乙個int型指標變數 int p 3 定義乙個int型指標陣列的變數 int 3 或 int d 3 定義乙個陣列指標變數 2.初始化賦值 假設二維陣列為 int a 3 3 1 用指標b表示二維陣列時為 int b a 0 將指標b指向a的首元素位址 二維陣列的表示方...
指標陣列 陣列指標 二維陣列指標
指標陣列 如果乙個陣列中的所有元素儲存的都是指標,那麼我們就稱它為指標陣列。除了每個元素的資料型別不同,指標陣列和普通陣列在其他方面都是一樣的,下面是 乙個簡單的例子 include int main 也可以不指定長度,直接寫作 int parr 定義乙個指向指標陣列的指標 int parr arr...