char (*p)[10];
char a[10];
p = a; // 警告:assignment from incompatible pointer type
為什麼 p = &a 正確,而 p = a 報警?
a 的雙重身份a 退化為指向首元素的指針,類型為 char *,值為 &a[0]。sizeof、& 操作元時:a 代表整個數組對象,類型為 char [10](或 char (*)[10] 經 & 取址後)。&a vs a(退化後)| 表達式 | 類型 | 值(地址數值) | 語義 |
|---|---|---|---|
a(退化) | char * | 0x7fff... | 首元素地址 |
&a | char (*)[10] | 0x7fff...(同值) | 整個數組地址 |
&a[0] | char * | 0x7fff...(同值) | 首元素地址 |
關鍵點:數值相同,**類型不同**。指針賦值需類型匹配(或兼容),char (*)[10] 不能直接接收 char *。
char (*p)[10] 是什麼?char 的數組的指針」。p+1 增加 sizeof(char[10]) = 10 字節,跳到下一個同樣大小的數組。*p 得到類型 char [10](退化為 char * 可訪問元素)。char p[] / char *p 是什麼?char p[]:定義一個數組,p 是數組名(非修飾的左值,不可賦值/自增)。char *p:定義一個指向 char 的指針,可指向單字符或字符串首元素。char (*p)[10];
char a[10];
strcpy(a, "hello"); // 初始化
p = &a; // 正確:類型匹配,均為 char (*)[10]
// 訪問元素
printf("p = %s\n", *p); // *p 退化為 char*,可作 %s
printf("2nd char = %c\n", (*p)[1]); // 顯式解引用後下標
| 宣告 | 名稱 | 含義 | sizeof(p) (32位) |
|---|---|---|---|
char (*p)[10] | 指向數組的指針 | 指向一個 10 元素數組 | 4(指針大小) |
char *p[10] | 指針數組 | 含 10 個 char* 的數組 | 40(10×4) |
char **p | 指向指針的指針 | 指向 char* 的指針 | 4 |
const 修飾,不可稱為「常量」。&a 和 a 內容相同?:它們無「內容」概念(非對象),僅有「值」(地址數值)。值相等,類型不同:char (*)[10] vs char *。p = a 能跑通?:編譯器僅警告,因底層地址數值相同,運行時「碰巧」能訪問。但類型系統已失效,p+1 會跳 10 字節而非 1 字節,導致邏輯錯誤。char (*p)[N]:**括號優先**,p 先結合 * → 指針 → 指向大小 N 的數組。char *p[N]:**下標優先**,p 先結合 [N] → 數組 → 元素是 char*。a:平時是「首元素指針」(char*),見 &/sizeof 變「整個數組」(char[N])。char (*p)[N] 必須用 &a,類型才對齊。掌握類型語義而非僅記語法,才能在複雜指針操作中游刃有餘。