指鈐是 C 語言的核心特性,也是初學者最容易困惑的難點。本文通過具體代碼示例,深入剖析數組名與指鈐的等價轉換、多維數組指鈐類型、結構體指鈐訪問成員的正規與非正規方法,以及內存對齊對指鈐運算的影響。
數組名 array 在不同表達式中扮演不同角色:
sizeof(array):代表整個數組,類型 int[10],結果為數組總大小。*array 或 array[0]:退化為指向首元素的指鈐,類型 int*。array + n:指向第 n 個元素的指鈐,sizeof(array+n) 為指鈐大小。示例:
int array[10] = {0,1,2,3,4,5,6,7,8,9};
value = *array; // 等價 array[0]
value = *(array + 3); // 等價 array[3]
char *str[3] 是指鈐數組,每個元素是 char*。數組名 str 類型為 char**,指向首元素 str[0]。*str 類型 char*,指向字符串首字符。*(str+1) 指向第二字符串首字符。strcpy(s, *str) 等價 strcpy(s, str[0])。
-> 運算符struct mystruct { int a, b, c; } ss = {20,30,40};
struct mystruct *ptr = &ss;
ptr->a; ptr->b; ptr->c; // 編譯器自動處理偏移與對齊
int* 逐字節訪問int *pstr = (int*)&ss;
*pstr; *(pstr+1); *(pstr+2); // 危險!
風險:結構體成員間可能因對齊要求插入填充字節,導致 *(pstr+1) 指向填充區而非成員 b。數組元素連續無間隙,結構體則不一定。此法僅適合調試查看填充情況。
sizeof、&array 除外。-> 或 . 運算符,切勿嘗試指鈐算術硬推偏移,除非極其清楚內存佈局且為特定目的。