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

C語言形式參數(形參)與實際參數(實參)深度解析

     編輯:C 語言問答

定義與核心區別

概念術語本質生命周期內存位置
形式參數 Parameter / 形參 函數定義/聲明中的變量,**佔位符** 函數調用時分配,返回時銷毀 被調用者棧幀局部變量區
實際參數 Argument / 實參 調用處提供的**具體值/變量/表達式** 調用者作用域決定 調用者棧幀/數據段/寄存器

代碼示例


// 函數定義:a、b 是形參
int add(int a, int b) {
    return a + b; // 使用形參
}

int main() {
    int x = 3, y = 5;     // x、y 是主調函數的局部變量
    int sum = add(x, y);  // x、y 作為實參傳遞
    // 也可直接用常量/表達式作實參
    int sum2 = add(10, 20); 
    int sum3 = add(x + 1, y * 2);
    return 0;
}

傳值調用機制

C 語言**只有傳值調用**。函數調用時,將實參的**值**拷貝一份給形參:


void modify(int p) {
    p = 20; // 修改形參副本
    printf("函數內 p = %d\n", p); // 輸出 20
}

int main() {
    int arg = 10;
    modify(arg); // 實參 arg 的值 (10) 被拷貝給形參 p
    printf("主函數 arg = %d\n", arg); // 輸出 10,未被修改
    return 0;
}

**結論**:函數內修改形參**不影響**實參原始值。

模擬傳引用:指針作形參

若需在函數內修改實參變量,**傳遞實參地址**,形參定義為指針:


void swap(int *a, int *b) { // 形參是指針
    int tmp = *a; *a = *b; *b = tmp;
}

int main() {
    int x = 3, y = 5;
    swap(&x, &y); // 實參是地址 &x, &y
    // x=5, y=3 實參值被修改
    return 0;
}

本質仍是傳值:拷貝了**地址值**,通過地址間接訪問實參內存。

進階:數組作參數的特殊性

數組名作實參時**退化為指向首元素的指針**,形參可寫為:


// 以下三種聲明等價,編譯器均視為 int *arr
void func1(int arr[]);
void func2(int arr[10]); // 10 被忽略,僅作文檔
void func3(int *arr);    // 最本質寫法

// 內部均可用 arr[i] 訪問,但 sizeof(arr) 返回指針大小,非數組大小
// 必須額外傳遞長度參數
void print_arr(int *arr, size_t len);

最佳實踐檢查清單

  • ✅ 形參名見名知義 (int max_retry 而非 int a)。
  • ✅ 不修改實參值的指針形參加 const (void print(const int *arr, int n))。
  • ✅ 大結構體傳指針避免棧拷貝開銷 (void process(const BigStruct *p))。
  • ✅ 可變參數函數 (printf 風格) 謹慎使用,優先考慮 C++ 可變參數模板或 C11 _Generic。
  • ❌ 絕不返回局部變量/形參地址 (棧內存釋放後成懸空指針)。

總結

形參是函數內部的「局部變量」,實參是調用者提供的「數據源」。C 語言通過「值拷貝」建立聯繫,若需雙向數據流,請顯式傳遞指針。 理解此點,是掌握 C 函數調用、避免「參數不生效」低級錯誤的鑰匙。

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