**函數參數聲明為數組(`T arr[]` 或 `T arr[N]`)實際上被編譯器調整為指針(`T *arr`)。** 數組名在表達式中(除 `sizeof`、`&`、`_Alignof` 外)轉換為指向首元素的指針。
#includevoid print_array_test(char ca[]) { printf("ca : %s\n", ca); printf("&ca : %p\n", (void*)&ca); // 參數自身地址(棧上) printf("&ca[0] : %p\n", (void*)&ca[0]); // 首元素地址 printf("&ca[1] : %p\n", (void*)&ca[1]); // 次元素地址 printf("*(ca+0) : %c\n", *(ca+0)); printf("*(ca+1) : %c\n", *(ca+1)); printf("ca+1 : %s\n", ca+1); } void print_ptr_test(char *pa) { printf("pa : %s\n", pa); printf("&pa : %p\n", (void*)&pa); // 參數自身地址 printf("&pa[0] : %p\n", (void*)&pa[0]); printf("&pa[1] : %p\n", (void*)&pa[1]); printf("pa+1 : %s\n", pa+1); printf("pa[1] : %c\n", pa[1]); printf("*(pa+1) : %c\n", *(pa+1)); printf("++pa : %s\n", ++pa); // 修改局部副本 } int main() { char abc[] = "hello,world!"; print_array_test(abc); print_ptr_test(abc); return 0; }
ca / pa 打印字符串內容相同&ca / &pa 為參數在棧上的地址(**不同**於數組首地址)&ca[0] / &pa[0] 等於傳入數組首地址ca+1 / `pa+1` 指向第二字符++pa 合法(修改局部指針副本),++ca **非法**(數組參數雖退化但不可修改)
main 棧幀: abc[14] → 'h','e','l','l','o',',','w','o','r','l','d','!','\0'
↑
首地址 0x7ffd...
print_array_test 棧幀: ca (指針) → 0x7ffd... (指向 abc 首元素)
&ca (ca 自身地址) = 0x7ffd... (不同位置)
| 表達式 | 含義 | 等價於 |
|---|---|---|
| arr[i] | 第 i 元素值 | *(arr + i) |
| &arr[i] | 第 i 元素地址 | arr + i |
| arr | 首元素地址 | &arr[0] |
| &arr | 整個數組地址 | 類型 T(*)[N],值同 arr 但類型不同 |