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

C語言參數傳遞:值傳遞 vs 位址傳遞完整圖解

     編輯:關於C

核心觀念:C 語言只有「值傳遞」

函數參數永遠是將實參的「值」複製給形參。若要在函數內修改呼叫端變數,必須傳遞該變數的「位址」(指標),再透過解參考操作間接修改。

程式碼示範與記憶體圖解

#include 

// 值傳遞:形參是實參的副本,修改不影響原變數
void pass_by_value(int a) {
    a++;
    printf("在 pass_by_value 內:a = %d\n", a);  // 2
}

// 位址傳遞:形參是指標,指向實參記憶體位置
void pass_by_address(int *a) {
    (*a)++;
    printf("在 pass_by_address 內:*a = %d\n", *a);  // 2
}

int main(void) {
    int n = 1;
    printf("呼叫前:n = %d\n", n);  // 1

    pass_by_value(n);
    printf("呼叫 pass_by_value 後:n = %d\n", n);  // 1(未變)

    pass_by_address(&n);  // 傳遞 n 的位址
    printf("呼叫 pass_by_address 後:n = %d\n", n);  // 2(已變)

    return 0;
}

記憶體模型對比

特性值傳遞位址傳遞
形參型別intint *
實參形式n&n
函數內修改方式a = 10*a = 10
對原變數影響無有
適用場景輸入參數、小型結構體輸出參數、大型結構體、陣列、需修改原值

進階應用:多重輸出參數

void divide(int dividend, int divisor, int *quotient, int *remainder) {
    if (divisor == 0) return;  // 錯誤處理略
    *quotient = dividend / divisor;
    *remainder = dividend % divisor;
}

int main() {
    int q, r;
    divide(10, 3, &q, &r);
    printf("商=%d 餘=%d\n", q, r);  // 商=3 餘=1
}

常見錯誤與避坑指南

  • ❌ void func(int *p) { p = &local_var; } —— 修改的是區域指標副本,不影響呼叫端指標。
  • ✅ void func(int **p) { *p = &local_var; } —— 傳遞指標的指標(雙重指標)才能修改呼叫端指標本身。
  • ❌ 解參考空指標或野指標 —— 呼叫前務必檢查指標有效性。
  • ✅ 使用 restrict 關鍵字(C99)告知編譯器指標不重疊,啟用更激進最佳化。

總結

「值傳遞」是 C 語言參數機制的唯一真相;「位址傳遞」是透過傳遞位址值來實現的間接修改技巧。熟練掌握兩者轉換,是編寫靈活、高效 C 函數介面的基石。

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