先來看看在一維數組中怎樣使用指針訪問數組:
一維數組中 a[i] 中的 a 代表了本數組的首地址,相當於 &a[0]。
因此 *a 就等於 a[0]。
那么對 a 加 1,就可以訪問下一位:
*(a+1) 就等於 a[1]。
可以看出,指針與數組的關系非常密切。好像兩個類型沒有什么差別,只是換個形式來表達而已。
其實這是因為數組在內存中是一塊連續的空間。這時候使用指針形式和數組形式來訪問數組並沒有差別。
那么在二維數組中如何用指針訪問呢?
我們首先來看看二維數組的構成以及如何訪問:
與一維數組類似的是,a[i][j] 中的 a 也代表了該數組在內存中的首地址。a 相當於 &a[0][0]。
可以將二維數組看作是由兩個一維數組構成的。假設有 a[2][2] 這樣一個二維數組,可以這么理解它:a 由 a[0],a[1],a[2] 構成,而 a[0] 又由 a[0][0],a[0][1],a[0][2] 構成,a[1] 由 a[1][0],a[1][1],a[1][2] 構成,a[2] 由 a[2][0],a[2][1],a[2][2] 構成。
所以如果將二維數組這樣(將序號用 a[i] 表示)來描述,會更加清晰:
[0] | [1] | [2] | |
---|---|---|---|
a[0] | 5 | 2 | 1 |
a[1] | 1 | 3 | 1 |
a[2] | 4 | 1 | 4 |
我們可以清晰地看到每一個 a[i][j] 都代表了誰:
知道二維數組的概念並會使用二維數組的方式來訪問數組后,我們就可以來談談如何用指針訪問二維數組了。
a 由 a[0],a[1],a[2] 構成,而 a[0] 又由 a[0][1],a[0][1],a[0][2] 構成
兩個一維數組構成了一個二維數組。a 是一個二維數組,a[i] 是一個一維數組。既然 a[i] 是一個數組,那么數組名就是這個數組的首地址。比如,a[0] 就等同於 &a[0][0]。
地址一旦出現,指針就可以登場了。
a 是一個數組名,它有三個元素:a[0],a[1],a[2]。所以:
*a 等於 a[0], *(a+1) 等於 a[1], *(a+2) 等於 a[2]。
a[0], a[1], a[2] 又都是各個一維數組的首地址。比如 a[0] 就等同於 &a[0][0],就是說 *a[0] = a[0][0]。
再結合上面的 *a 等於 a[0],可以得出:**a 等於 a[0][0]。
以 a[2][2] 為例,指針與數組的等價關系如下表所示:
數組元素 | 指針訪問 |
---|---|
a[0][0] | **a |
a[0][1] | *(*a+1) |
a[0][2] | *(*a+2) |
a[1][0] | **(a+1) |
a[1][1] | *(*(a+1)+1) |
a[1][2] | *(*(a+1)+2) |
a[2][0] | **(a+2) |
a[2][1] | *(*(a+2)+1) |
a[2][2] | *(*(a+2)+2) |
雖然看起來很繁瑣,但是可以總結成一句話:
二維數組 a[i][j] 中的 a[i] 是一個一維數組名,也就是一個地址量。
再記住二維數組的描述圖:
[0] [1] [2] a[0] a[1] a[2]
記住這兩個點,就可以清晰地明確二維數組的概念以及如何用指針訪問二維數組中的元素了。
我們知道字符串是一個一維數組,那么多個字符串就可以用字符串數組來表達。
現在我們來定義並初始化一個二維數組:
char s[3][5] = {"I", "love", "you"};
上面定義了一個 3 行 5 列的二維數組。在內存中存放格式如下:
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
s[0] | I | \0 | |||
s[1] | l | o | v | e | \0 |
s[2] | y | o | u | \0 |
如果使用指針,可以這么初始化:
char *s[] = "I", "love", "you"};
在內存中存放的格式與使用二維數組初始化有些不同:
.... 0 1 2 3 4
s[0] I \0
s[1] l o v e \0
s[2] y o u \0
可以看出,借助指針對二維數組初始化時,省去了不必要的空間,對內存空間的利用率更高。
訪問字符串數組:
通常對字符串的處理,傳入的的參數都是字符串的首地址,也就是字符串名。
比如:
char s[80]; // 定義一個長度為 80 的字符串 s
char t[80]; // 定義一個長度為 80 的字符串 t
gets (s); // 讀入一個字符串
pus (s); // 輸出一個字符串
strcpy (s, t); // 將字符串 t 拷貝到 字符串 s 中
其中的 s 都是該字符串的首地址。
上小節里面我們提到:
二維數組 a[i][j] 中的 a[i] 是一個一維數組名,也就是一個地址量。
所以這里上面的字符串數組 s 中的 s[1] 就是一個一維數組,是一個地址量,代表了 "love" 這個字符串數組,是它的首地址。
所以如果我們想輸出 "love" 這個字符串,可以這樣寫:
puts (s[1]);
如果你想用指針訪問,可以這樣寫:
puts (*(s+1));
這樣會比數組的形式復雜點。
文章主要解釋了二維數組的構成、如何用指針訪問數組以及關於字符串數組的一點問題。
希望上面的解釋可以讓你對二維數組有一個視覺上的印象(那個描述圖)。因為二維數組構成上的一些特點,我們可以借助指針來訪問它,雖然相比使用數組形式訪問繁瑣點,但通過這個過程可以讓我們對二維數組的構成更加清晰明了。
在字符串數組的初始化上顯然更建議用指針數組來進行初始化,這樣能更好地利用內存空間。
但在訪問字符串數組(或者其他二維數組)上,用數組形式更加簡潔、清晰。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。