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

C語言形參與實參深度解析:傳值調用、模擬傳址、陣列退化、可變參數

     編輯:C 語言問答

定義與核心機制

  • 形參 (Formal Parameter): 函式定義/宣告中括號內的變數,僅在函式內部可見,佔用棧幀空間。
  • 實參 (Actual Argument): 調用點傳入的表達式/變數/常數,求值後將結果複製給對應形參。
  • C 語言唯一調用約定:傳值調用 (Call by Value)。 實參值被複製,函式內修改形參不影響實參原變數。

經典範例

#include <stdio.h>

void swap_val(int a, int b) { // 形參
    int t = a; a = b; b = t;
    printf("swap_val 內: a=%d, b=%d\n", a, b);
}

void swap_ptr(int *pa, int *pb) { // 形參為指標,模擬傳址
    int t = *pa; *pa = *pb; *pb = t;
}

int main() {
    int x = 3, y = 5; // 實參變數
    printf("調用前: x=%d, y=%d\n", x, y);
    swap_val(x, y);   // 實參為 x, y (值 3, 5 複製給形參 a, b)
    printf("swap_val 後: x=%d, y=%d\n", x, y); // x,y 不變
    swap_ptr(&x, &y); // 實參為 &x, &y (位址值複製給形參 pa, pb)
    printf("swap_ptr 後: x=%d, y=%d\n", x, y); // x,y 交換成功
    return 0;
}

特殊情況:陣列實參退化為指標

void func(int arr[]) {          // 等價於 void func(int *arr)
    printf("sizeof(arr) = %zu\n", sizeof(arr)); // 印出指標大小 (4/8),非陣列大小
    arr[0] = 999;                 // 修改原陣列首元素
}

int main() {
    int a[5] = {1,2,3,4,5};
    printf("sizeof(a) = %zu\n", sizeof(a)); // 20 (5*4)
    func(a); // 實參 a 退化為 int* (首元素位址)
    printf("a[0] = %d\n", a[0]); // 999
    return 0;
}
  • 若需在函式內獲得陣列長度,**必須額外傳遞長度參數** 或使用結構體包裹 (柔性陣列成員)。
  • 多維陣列退化:`int a[3][4]` → `int (*)[4]` (指向含 4 個 int 陣列的指標),第二維度長度必須在形參聲明中給出。

可變參數 (``)

#include <stdarg.h>
#include <stdio.h>

void print_ints(int count, ...) {
    va_list ap;
    va_start(ap, count);
    for (int i = 0; i < count; ++i) {
        int val = va_arg(ap, int); // 必須知道類型
        printf("%d ", val);
    }
    va_end(ap);
    printf("\n");
}

int main() {
    print_ints(5, 10, 20, 30, 40, 50);
    return 0;
}

最佳實踐

  1. 標量參數預設 `const` 形參 (`void func(const int x)`) 表示不修改,若需修改用指標 (`void func(int *px)`)。
  2. 大型結構體傳遞:用 `const struct Big *` 避免棧拷貝開銷。
  3. 陣列參數:聲明為 `void func(const int *arr, size_t n)` 或 `void func(const int arr[static n])` (C99 靜態長度提示)。
  4. 字串參數:`void func(const char *s)`,約定以 `\0` 結尾。
  5. 可變參數:僅用於類 `printf` 格式化場景,嚴格檢查格式字串與參數匹配 (`-Wformat`)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved