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

C/C++ 參數傳遞機制:值傳遞、指標傳遞與引用傳遞深度解析

     編輯:關於C++

函數參數傳遞機制的基本理論

函數參數傳遞本質上是主調函數與被調函數之間的通訊方式。主要有兩種基本機制:值傳遞 與 引用傳遞。

  • 值傳遞:形式參數作為區域變數在堆疊開闢空間,儲存實參的值的副本。被調函數對形參的任何操作不影響實參。
  • 引用傳遞:形式參數在堆疊儲存實參的位址。被調函數對形參的操作經由間接定址存取實參,故會影響實參。

C 語言:唯有值傳遞

C 語言只有值傳遞。許多人誤以為傳遞指標是引用傳遞,實則不然——指標變數的值(即位址)被複製傳遞。

void swap(int *x, int *y) {
    int temp = *x; *x = *y; *y = temp;
}
void main() {
    int a = 1, b = 2;
    int *p1 = &a, *p2 = &b;
    swap(p1, p2); // 傳遞指標的「值」(位址),屬值傳遞
}

關鍵觀念:

  1. 堆疊是主調/被調函數通訊的主要區域。
  2. C 語言參數從右向左入堆疊。
  3. 被調函數堆疊結構:區域變數 → 返回位址 → 函數參數(低址→高址)。
  4. 調用端負責清理堆疊;返回值通常置於暫存器(支援中斷、避免被覆寫)。

C++:三種傳遞方式

C++ 提供三種參數傳遞方式:

  1. 傳值呼叫
  2. 傳址呼叫(傳指標)
  3. 引用傳遞

另有全域變數傳遞(廣義上包含類別成員變數、static 變數、namespace 限定變數),效率最高但不支援多執行緒,工程上應謹慎使用。

1. 功能面:何時能修改實參?

// 傳值:無法修改實參
void swap(int a, int b) { int t=a; a=b; b=t; }

// 傳指標:可修改實參
void swap(int *pa, int *pb) { int t=*pa; *pa=*pb; *pb=t; }

// 傳引用:可修改實參,語法更直觀
void swap(int &ra, int &rb) { int t=ra; ra=rb; rb=t; }

2. 傳遞效率:參數複製的開銷

  • 內建型別(≤4 bytes):32 位元 CPU 下,值傳遞與指標傳遞同為 4 bytes,效率相當;64 位元 CPU 同理。
  • 8 bytes 型別:32 位元 CPU 需兩次傳遞,值傳遞較慢;64 位元 CPU 則相同。
  • 自訂型別:值傳遞會觸發建構/解構函式,開銷大;指標/引用傳遞僅複製位址,效率高。
  • 引用傳遞:通常以指標實作,效率與指標相當;編譯器優化時可能採用直接定址,效率更高。

3. 執行效率:函數體內操作的開銷

值傳遞在函數體內採直接定址,指標/引用採間接定址。若函數體內頻繁操作參數,間接定址會造成明顯效能損失。

4. 類型安全性

  • 值傳遞、引用傳遞:強型別檢查。
  • 指標傳遞:型別檢查較弱,void* 幾乎無檢查,易產生 Bug。

5. 多型情況

若形參為父類別、實參為子類別,值傳遞會導致物件切割——僅建構父類別部分,失去子類別特有行為(虛函式無法正常運作)。此時必須用指標或引用。

6. 參數檢查與健壯性

值/引用傳遞無法傳遞「不存在的值」;指標可能傳遞野指標、懸空指標。健壯程式碼優先使用值或引用傳遞。

7. 彈性

指標可傳遞 nullptr 表示「無物件」,標準庫 time() 即利用此特性。此為指標獨有優勢。

綜合建議

  • 內建型別:優先值傳遞。
  • 自訂型別、大型物件:優先const 引用傳遞(const T&),兼顧效率與安全。
  • 需修改實參:使用非 const 引用或指標。
  • 需表達「可選參數」:使用指標(可傳 nullptr)。

實用技巧

1. const 關鍵字

輸入參數加 const 防止誤修改,也是文件化介面意圖:

int strlen(const char *str); // 承諾不修改 str 指向的資料
int strlen(const char *const str); // 連指標本身也不允許修改(較少見)

成員函數後加 const 表示不修改物件狀態:

class Person {
    unsigned char age() const; // 僅讀取 m_age
    unsigned char m_age;
};

2. 預設參數值

減少多載函數數量,但 C# 移除此特性(安全考量),使用時需謹慎。

3. 參數順序

同名函數的共同參數盡量置於相同位置,方便呼叫端。

4. 常用慣用語:const 引用

void swap(const int& x, const int& y); // 函數體內無法修改 x、y
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved