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

C++ 函數參數傳遞三大方式全解析:值傳遞、指針傳遞與引用傳遞

     編輯:C++ 入門

概述

C++ 函數參數傳遞方式直接影響程序的性能、語義正確性與內存安全。C++ 提供了三種核心機制:**值傳遞**、**指針傳遞**、**引用傳遞**。本文將通過代碼對比、內存模型分析與最佳實踐指南,幫助你徹底掌握它們的異同與選擇策略。

三種方式代碼對比

1. 值傳遞 — 複製副本


void func_val(int x) {
    x += 5; // 修改的是副本,不影響原值
}

int main() {
    int y = 0;
    func_val(y);
    cout << "y = " << y << endl; // 輸出: y = 0
}

特點:函數內部操作的是實參的拷貝(在棧上開闢臨時空間)。原變量不受影響。缺點:大對象拷貝開銷大,效率低。

2. 指針傳遞 — 傳遞地址


void func_ptr(int *x) {
    *x += 5; // 通過地址修改原內存單元
}

int main() {
    int y = 0;
    func_ptr(&y); // 傳遞地址
    cout << "y = " << y << endl; // 輸出: y = 5
}

特點:傳遞變量地址,函數內通過解引用修改原值。可傳 nullptr 表示「無對象」。語法稍繁瑣(需 & 取址、* 解引用)。

3. 引用傳遞 — 別名機制


void func_ref(int &x) {
    x += 5; // 直接操作原變量 (x 是 y 的別名)
}

int main() {
    int y = 0;
    func_ref(y); // 語法同值傳遞,效果同指針傳遞
    cout << "y = " << y << endl; // 輸出: y = 5
}

特點:語法最簡潔(調用處無需 &),效率同指針(無拷貝),語義最清晰(不可為空,綁定後不變)。現代 C++ 首選方式。

進階話題:const 與參數傳遞的結合

值傳遞 + const?

值傳遞本身已產生副本,函數內修改不影響外部,無需 加 const 修飾參數(參數本身就是局部副本)。

用戶定義類型 (UDT/ADT) 的「值傳遞」陷阱

對類類型,值傳遞會觸發拷貝構造函數(構造臨時對象 → 複製 → 析構),開銷極大。


// 低效:產生臨時對象,調用構造/拷貝/析構
void func(A a); 

// 高效:引用傳遞,無臨時對象。加 const 防止誤修改
void func(const A &a); 

鐵律:除基本類型外,輸入參數優先用 const T&。

指針傳遞 + const 保護

  • void f(const int *p):保護指向的數據不被修改(*p = 10 報錯)。
  • void f(int *const p):保護指針本身不被修改指向(p = &other 報錯)。
  • void f(const int *const p):雙重保護。

// 經典 strcpy 簽名:保護源字符串不被修改
void strcopy(char *dest, const char *src); 

選擇決策樹

  1. 基本類型、小型結構體(如 std::pair、迭代器)且不需修值 → 值傳遞。
  2. 需修改實參 → 引用傳遞 (T&)(首選)或指針 (T*)(需表達可選性時)。
  3. 不需修改實參 (大多數情況) → const 引用 (const T&)。
  4. 需表達「無對象/可選」 → 指針 (T*) 或 std::optional (C++17)。
  5. 多態基類參數 → 指針 或 引用(配合虛函數)。

總結

值傳遞語義獨立但有拷貝開銷;指針傳遞靈活但語法繁瑣且有空指針風險;引用傳遞結合了效率與安全,是現代 C++ 參數傳遞的默認首選。善用 const 配合引用/指針,能在編譯期構建堅實的防禦性編程防線。

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