| 概念 | 術語 | 本質 | 生命周期 | 內存位置 |
|---|---|---|---|---|
| 形式參數 | 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 函數調用、避免「參數不生效」低級錯誤的鑰匙。