首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言數組參數退化為指針的本質解析:內存布局與實戰驗證

     編輯:關於C語言

核心結論

**函數參數聲明為數組(`T arr[]` 或 `T arr[N]`)實際上被編譯器調整為指針(`T *arr`)。** 數組名在表達式中(除 `sizeof`、`&`、`_Alignof` 外)轉換為指向首元素的指針。

實戰驗證代碼

#include 

void 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... (不同位置)

等價關係總結

最佳實踐建議

  1. 函數參數**統一聲明為指針** `void func(int *arr, size_t len)`,語義更清晰
  2. 必須傳遞長度,避免越界
  3. 只讀數組加 `const`:`void func(const int *arr, size_t len)`
  4. 需修改指針本身(如輸出參數)用二級指針:`void func(int **out_arr, size_t *len)`

總結

「數組參數退化為指針」是 C 語言為了效率(避免拷貝整個數組)做出的歷史妥協。理解退化本質、內存布局、類型差異(`T*` vs `T(*)[N]`),能避免 90% 的數組/指針相關 Bug。現代 C 編程建議**顯式使用指針+長度**,拒絕隱式退化帶來的認知負擔。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
表達式含義等價於
arr[i]第 i 元素值*(arr + i)
&arr[i]第 i 元素地址arr + i
arr首元素地址&arr[0]
&arr整個數組地址類型 T(*)[N],值同 arr 但類型不同