C 語言中數組名與指針的關係是經典難點。本文通過實例深入剖析 cc、&cc、&cc+1 等表達式的真實含義,揭示數組名的雙重身份與 sizeof 編譯時求值特性。
定義 int cc[10]; 在 32 位機上(假設首地址 0x28ff00):
cc、cc+1、&cc[0]:指向首元素,類型 int*,步長 4 字節&cc:指向整個數組,類型 int(*)[10],步長 40 字節(整個數組大小)&cc+1:地址 0x28ff28(0x28ff00 + 40),即數組末尾下一個位置
&cc 代表整個數組對象,類型為「指向含 10 個 int 的數組的指針」。這解釋了為何 &cc+1 跳過整個數組,而非單個元素。
數組名本質是代表數組對象的左值,但在以下兩種情況**不**轉換為指針:
sizeof 操作數:sizeof(cc) = 40(整個數組大小)& 操作數:&cc 類型為 int(*)[10]其他所有場合(如賦值給指針、傳參、算術運算),數組名自動轉換為指向首元素的指針常量(右值)。
int cc[10]; sizeof(cc[0]) // 4,單個 int 大小 sizeof(cc) // 40,數組總大小(此處 cc 為左值,類型 int[10]) sizeof(&cc) // 4,指針大小(32 位機) sizeof(int(*)[10]) // 4,同 &cc 類型
int *p[2]; // 指針數組:2 個 int* 指針 sizeof(p) // 8,兩個指針大小 sizeof(&p) // 4,指向指針數組的指針大小 *p // 隨機值,p 未初始化
char str[] = "hactrox"; // 字符數組,含結束符 \0,長度 8 char *p = str; // 指向首字符 sizeof(str) // 8,數組大小 sizeof(p) // 4,指針大小
int[10])的左值&數組名 獲取的是數組指針,步長為整個數組大小sizeof 在編譯期計算,不求值表達式(如 sizeof(printf("x")) 不會打印)指針數組(int *p[10])與 數組指針(int (*p)[10])徹底理解這些本質區別,是寫出正確、高效 C 代碼的基石。