數組名在大多數表達式中會退化為指向首元素的指針,但sizeof和&運算符除外。這個簡短程序直觀展示了數組、指針、地址運算的關係。
#include <stdio.h>
int main(void) {
long multiple[] = {15L, 25L, 35L, 45L};
long *p = multiple; // p指向數組首元素,等價於 &multiple[0]
for (int i = 0; i < sizeof(multiple) / sizeof(multiple[0]); ++i) {
printf("address p+%d (&multiple[%d]): %llu *(p+%d) value: %ld\n",
i, i, (unsigned long long)(p + i), i, *(p + i));
}
printf("\n type long occupies: %zu bytes\n", sizeof(long));
return 0;
}
long *p = multiple;:數組名multiple退化為&multiple[0],類型為long*,賦給指針pp + i:指針算術運算,地址增加i * sizeof(long)字節*(p + i):解引用獲取值,等價於multiple[i]或p[i]sizeof(multiple):整個數組大小(此處4×8=32字節),不退化&multiple:數組指針,類型long(*)[4],&multiple + 1跨越整個數組address p+0 (&multiple[0]): 140734799804416 *(p+0) value: 15 address p+1 (&multiple[1]): 140734799804424 *(p+1) value: 25 address p+2 (&multiple[2]): 140734799804432 *(p+2) value: 35 address p+3 (&multiple[3]): 140734799804440 *(p+3) value: 45 type long occupies: 8 bytes
數組名的三種例外情況(不退化為指針):
sizeof(array):返回整個數組字節大小&array:返回數組指針(類型T(*)[N]),而非元素指針char str[] = "hello";此處str是數組,非指針掌握數組與指針的聯繫與區別,是寫好C語言、理解內存佈局、避免指針錯誤的基石。