From Gossip@caterpillar

C Gossip: 指標與陣列

在宣告一個陣列之後,陣列名稱用來參考至陣列的第一個元素的記憶體位址,例如在下面的程式中將指出,陣列arr與&arr[0]所指向的 位置是相同的:
#include <stdio.h>

int main(void) {
int arr[10] = {0};

printf("arr :\t\t%X\n", arr);
printf("&arr[0] :\t%X\n", &arr[0]);

return 0;
}

執行結果:
arr :           22FF20
&arr[0] :       22FF20


之前也曾經討論過,陣列的索引其實是相對於第一個記憶體位址的位移量,下面這個程式以指標運算與陣列索引操作,顯示出相同的對應位址值:
#include <stdio.h>
#define LENGTH 10

int main(void) {
int arr[LENGTH] = {0};
int *ptr = arr;
int i;

for(i = 0; i < LENGTH; i++) {
printf("&arr[%d]: %X", i ,&arr[i]);
printf("\t\tptr + %d: %X\n", i, ptr + i);
}

return 0;
}

 
執行結果:
&arr[0]: 22FF20         ptr + 0: 22FF20
&arr[1]: 22FF24         ptr + 1: 22FF24
&arr[2]: 22FF28         ptr + 2: 22FF28
&arr[3]: 22FF2C         ptr + 3: 22FF2C
&arr[4]: 22FF30         ptr + 4: 22FF30
&arr[5]: 22FF34         ptr + 5: 22FF34
&arr[6]: 22FF38         ptr + 6: 22FF38
&arr[7]: 22FF3C         ptr + 7: 22FF3C
&arr[8]: 22FF40         ptr + 8: 22FF40
&arr[9]: 22FF44         ptr + 9: 22FF44


在這個程式中,您將陣列的第一個元素位址指定給ptr,然後對ptr作遞增運算,每遞增一個單位,其與陣列相對應索引的元素之記憶體位址都相同,這可以說 明陣列索引的背後意義。

您也可以利用指標運算來取出陣列的元素值,如以下的程式所示:
#include <stdio.h>
#define LENGTH 5

int main(void) {
int arr[LENGTH] = {10, 20, 30, 40, 50};
int *ptr = arr;
int i;

// 以指標方式存取資料
for(i = 0; i < LENGTH; i++) {
printf("*(ptr + %d): %d\n", i , *(ptr + i));
}
putchar('\n');

// 以陣列方式存取資料
for(i = 0; i < LENGTH; i++) {
printf("ptr[%d]: %d\n", i, ptr[i]);
}
putchar('\n');

// 以指標方式存取資料
for(i = 0; i < LENGTH; i++) {
printf("*(arr + %d): %d\n", i , *(arr + i));
}
putchar('\n');

// 以陣列方式存取資料
// 以陣列方式存取資料
for(i = 0; i < LENGTH; i++) {
printf("arr[%d]: %d\n", i, arr[i]);
}
putchar('\n');

return 0;
}

執行結果:
*(ptr + 0): 10
*(ptr + 1): 20
*(ptr + 2): 30
*(ptr + 3): 40
*(ptr + 4): 50

ptr[0]: 10
ptr[1]: 20
ptr[2]: 30
ptr[3]: 40
ptr[4]: 50

*(arr + 0): 10
*(arr + 1): 20
*(arr + 2): 30
*(arr + 3): 40
*(arr + 4): 50

arr[0]: 10
arr[1]: 20
arr[2]: 30
arr[3]: 40
arr[4]: 50


在上面的程式中,您可以使用指標運算配合*運算子來取出陣列中的每個元素,也可以配合下標運算子來取出陣列元素。