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

C語言函數數組參數本質解析:退化為指標與修改風險

     編輯:關於C語言

核心結論:數組參數即指標

在 C 語言中,數組作為函數參數時會退化為指向首元素的指標。無論形參寫作 int arr[]、int arr[10] 或 int *arr,在函數內部完全等價,sizeof(arr) 返回指標大小而非數組大小。

三種等價聲明形式

// 形式1:數組語法(長度被忽略)
void getArr(int p[], int si);

// 形式2:直接聲明指標(推薦,語義清晰)
void getArr(int *p, int si);

// 形式3:指定長度(無任何作用,僅作文檔)
void getArr(int p[2], int si);  // 仍可傳入任意長度數組

所有形式編譯後無任何區別,均為接收指標。

傳遞機制:隱式傳址(引用語義)

  • 調用者傳遞數組名(首元素地址)。
  • 函數接收指標,可直接修改原數組內容。
  • 這是 C 語言中實現函數修改實參的唯一途徑(除非傳結構體指標)。

修改風險示例

void getArr(int p[], int si) {
    for (int i = 0; i < si; i++) p[i]++;  // 修改原數組!
}

int main() {
    int ns[] = {1,2,3,4,5};
    getArr(ns, 5);
    // ns 變為 {2,3,4,5,6}
}

防止修改:加 const

void printArr(const int *p, int si) {  // 或 const int p[]
    // p[i]++ 編譯錯誤
    for (int i = 0; i < si; i++) printf("%d ", p[i]);
}

字符數組特例:隱含結束標記

void getArr(char p[]) {  // 無需傳長度
    for (int i = 0; p[i]; i++)  // 以 '\0' 判斷結束
        printf("%c: %d\n", p[i], p[i]);
}

利用字符串以 \0 結尾特性,省去長度參數。

多維數組參數:僅首維退化

void func(int arr[][10], int rows);  // 必須指定第二維大小
void func(int (*arr)[10], int rows); // 等價:指向含10個int數組的指標

編譯器需要知道每行大小以計算偏移,故第二維不可省略。

最佳實踐建議

  1. 形參寫 int *arr:明確語義為指標,避免誤以為傳遞整個數組。
  2. 必傳長度參數:除字符串外,無法在函數內推導數組長度。
  3. 只讀加 const:防止意外修改,文檖接口契約。
  4. 需傳遞整個數組副本:包裹在結構體中 struct { int data[10]; },結構體傳值會複製全部內容。

總結

「數組參數退化為指標」是 C 語言最基礎也最易誤解的機制之一。理解其本質為傳址調用,配合 const 與長度參數,即可安全高效地處理數組參數。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved