Home [C# 筆記] 參數傳遞 (Call by Value & Call by Reference)
Post
Cancel

[C# 筆記] 參數傳遞 (Call by Value & Call by Reference)

參數傳遞(Parameter Passing)方式有兩種:

  1. 傳值呼叫(Call by Value)
  2. 傳參考呼叫(Call by Reference)

傳值呼叫(Call by value)

「傳值呼叫(Call by value)」就是主程式將參數值傳給方法,執行方法後,所傳入的參數值為無論怎麼修改它,都不會因此而更動到主程式裡的參數值。

故在傳遞參數時,其實是重新複製一個參數,再將此「複製參數」傳遞給方法。

此「複製參數」稱為「虛擬參數」,方法內的「虛擬參數」與主程式中的「實際參數」位於不同的記憶體位址。

由於Call by value需要額外記憶體,故binding time最晚。

  • 優點:沒有副作用(side effect)
  • 缺點:較佔記憶空間。
  • 使用時機:傳送小量資料。

範例

將 n 傳入 Test()方法中,執行 +10 動作後,n仍然為10

1
2
3
4
5
6
7
8
9
//主程式
int n = 10;
Test(n); //將n傳入方法中,執行+10動作後
Console.WriteLine(n); //n仍然為10

//方法
void Test(int number) {
    number += 10; //20
}

number、n 兩塊不同的空間(不同記憶體位址)

傳參考呼叫(Call by reference)

「傳參考呼叫(Call by reference)」就是主程式將參數值傳遞給方法,執行後,只要方法有修改到所傳入的參數值,就會更動影響到主程式裡的參數值,

故在傳遞參數時,方法內的「虛擬參數」與主程式中的「實際參數」位於「相同」的記憶體位址,故稱「Call by reference」。

  • 優點:節省記憶空間、傳遞速度快。
  • 缺點:有副作用(side effect)
  • 使用時機:適合傳送大量資料。

範例:參數加上 ref

寫一方法,參數加上ref
將 n 傳入 Test() 方法中,執行 +10 動作後,n 變成為20。

1
2
3
4
5
6
7
8
9
//主程式
int n = 10;
Add(ref n);
Console.WriteLine(n); //20

//方法
void Add(ref int number) { //參數加上ref
    number += 10;
}

原本 number、n 是兩塊不同的空間(不同記憶體位址),
執行後,number、n 指向相同位址。

number、n 他們本來不是同一塊空間,加了ref,他們在Stack(堆疊/棧)地址是一樣的,變成同一塊空間。

為什麼 number = 20?

因為ref的作用能把一個變量以參數的形式帶到一個方法中進行改變。
再將改變後的值從方法中帶出來。

結論

由此可知,「call by value(傳值呼叫)」 當從主程式傳入參數時,經方法運算之後,並不會影響主程式所傳入的參數值,

而「call by reference(傳參考呼叫)」當主程式傳入參數時,經方法運算之後,會指向同一個記憶體位址,

所以也影響了主程式當時所傳入的參數值。

最簡單的概念講法就是:call by value 沒有副作用,而call by reference有副作用

ref 參數

ref 的好處就是,不用再寫返回值了

  • 能夠將一個變量帶入一個方法中進行改變,改變完成後,再將改變後的值帶出方法。
  • ref 參數要求在方法外必須為其賦值,而方法可以不賦值。

它能夠把一個變量以參數的型式傳遞給一個方法, 在一個方法中進行改變,
改變完成後,再把這個值自動的,就是改變後的值自動的給我帶出來。

在一個方法裡面改變這個變數,方法外面這個變數也跟著改變。

範例

在方法的參數前加ref即可 void Test( ref int i) { }

1
2
3
4
5
6
7
8
9
10
11
12
public static void Main()
{
    int salary = 20000; //salary的值會帶入ref參數方法裡面
    SalaryIncrease(ref salary); //調薪。Call ref參數的調薪方法
    Console.WriteLine(salary); //25000
}

// ref參數 的 調薪方法
static void SalaryIncrease(ref int salary) 
{
    salary += 5000;
}

[C# 筆記] 值傳遞 & 引用傳遞 by R
[C# 筆記] ref 參數 by R
Book: Visual C# 2005 建構資訊系統實戰經典教本

This post is licensed under CC BY 4.0 by the author.

[C# 筆記] 方法的宣告、呼叫、存取範圍

[C# 筆記] 方法參數的使用(ref、out、params)