C 指標和陣列
指標與陣列
您也可以使用指標來訪問 陣列。
考慮下面的整數陣列
示例
int myNumbers[4] = {25, 50, 75, 100};
您從 陣列章節 中瞭解到,您可以使用 for
迴圈遍歷陣列元素
示例
int myNumbers[4] = {25, 50, 75, 100};
int i;
for (i = 0; i < 4; i++) {
printf("%d\n", myNumbers[i]);
}
結果
25
50
75
100
與其列印每個陣列元素的值,不如列印每個陣列元素的記憶體地址
示例
int myNumbers[4] = {25, 50, 75, 100};
int i;
for (i = 0; i < 4; i++) {
printf("%p\n", &myNumbers[i]);
}
結果
0x7ffe70f9d8f0
0x7ffe70f9d8f4
0x7ffe70f9d8f8
0x7ffe70f9d8fc
注意,每個元素的記憶體地址的最後一位數字都不同,增加了 4。
這是因為 int
型別的大小通常是 4 位元組,還記得嗎?
所以從上面的“記憶體地址示例”中,您可以看到編譯器為每個陣列元素保留了 4 位元組的記憶體,這意味著整個陣列佔用了 16 位元組(4 * 4)的記憶體儲存空間
示例
int myNumbers[4] = {25, 50, 75, 100};
// 獲取 myNumbers 陣列的大小
printf("%lu", sizeof(myNumbers));
結果
16
指標與陣列有什麼關係?
好的,那麼指標和陣列有什麼關係呢?在 C 語言中,陣列的名稱實際上是該陣列第一個元素的指標。
感到困惑?讓我們來更好地理解這一點,並再次使用上面的“記憶體地址示例”。
第一個元素的記憶體地址與陣列的名稱相同
示例
int myNumbers[4] = {25, 50, 75, 100};
// 獲取 myNumbers 陣列的記憶體地址
printf("%p\n", myNumbers);
// 獲取第一個陣列元素的記憶體地址
printf("%p\n", &myNumbers[0]);
結果
0x7ffe70f9d8f0
0x7ffe70f9d8f0
這基本上意味著我們可以透過指標來運算元組!
怎麼做?由於 myNumbers 是 myNumbers 中第一個元素的指標,您可以使用 *
運算子來訪問它
示例
int myNumbers[4] = {25, 50, 75, 100};
// 獲取 myNumbers 中第一個元素的值
printf("%d", *myNumbers);
結果
25
要訪問 myNumbers 中的其餘元素,您可以遞增指標/陣列(+1, +2, 等)
示例
int myNumbers[4] = {25, 50, 75, 100};
// 獲取 myNumbers 中第二個元素的值
printf("%d\n", *(myNumbers + 1));
// 獲取 myNumbers 中第三個元素的值
printf("%d", *(myNumbers + 2));
// 以此類推..
結果
50
75
或者遍歷它
示例
int myNumbers[4] = {25, 50, 75, 100};
int *ptr = myNumbers;
int i;
for (i = 0; i < 4; i++) {
printf("%d\n", *(ptr + i));
}
結果
25
50
75
100
也可以使用指標更改陣列元素的值
示例
int myNumbers[4] = {25, 50, 75, 100};
// 將第一個元素的值更改為 13
*myNumbers = 13;
// 將第二個元素的值更改為 17
*(myNumbers +1) = 17;
// 獲取第一個元素的值
printf("%d\n", *myNumbers);
// 獲取第二個元素的值
printf("%d\n", *(myNumbers + 1));
結果
13
17
這種處理陣列的方式可能看起來有點多餘。特別是對於上面示例中簡單的陣列。但是,對於大型陣列,使用指標來訪問和運算元組會更有效率。
透過指標訪問二維陣列也被認為更快速和更容易。
由於字串實際上是陣列,您也可以使用指標來訪問字串。
目前,您知道這是如何工作的就足夠了。但正如我們在上一章中提到的;指標必須小心處理,因為有可能覆蓋儲存在記憶體中的其他資料。