C 中關鍵字ref與out的區別

2022-02-12 22:59:33 字數 2495 閱讀 4898

在c#中,ref與out是很特殊的兩個關鍵字。使用它們,可以使引數按照引用來傳遞。

總的來說,通常我們向方法中傳遞的是值.方法獲得的是這些值的乙個拷貝,然後使用這些拷貝,當方法執行完畢後,這些拷貝將被丟棄,而原來的值不將受到影響.此外我們還有其他向方法傳遞引數的形式,引用(ref)和輸出(out).

有時,我們需要改變原來變數中的值,這時,我們可以向方法傳遞變數的引用,而不是變數的值.引用是乙個變數,他可以訪問原來變數的值,修改引用將修改原來變數的值.變數的值儲存在記憶體中,可以建立乙個引用,他指向變數在記憶體中的位置.當引用被修改時,修改的是記憶體中的值,因此變數的值可以將被修改.當我們呼叫乙個含有引用引數的方法時,方法中的引數將指向被傳遞給方法的相應變數,因此,我們會明白,為什麼當修改引數變數的修改也將導致原來變數的值.

通俗的從功能上來講,使用這兩個關鍵字,可以使乙個方法返回多個引數。

msdn中的定義:

ref 關鍵字使引數按引用傳遞。其效果是,當控制權傳遞**用方法時,在方法中對引數所做的任何更改都將反映在該變數中。若要使用 ref 引數,則方法定義和呼叫方法都必須顯式使用 ref 關鍵字。

out 關鍵字會導致引數通過引用來傳遞。這與 ref 關鍵字類似,不同之處在於 ref 要求變數必須在傳遞之前進行初始化。若要使用 out 引數,方法定義和呼叫方法都必須顯式使用 out 關鍵字。

首先,我們來看乙個簡單的例子:

static void testrefandout()

static void testref(ref string str)

在testrefandout()中將字串s1以ref關鍵字的方式傳到方法testref(ref string str)中,在這個方法中,我們改變了s1的引用變數str的值,最後,回到testrefandout()方法後輸出s1的值,發現其值已被改變。

將上例中的ref換成out,**如下:

static void testrefandout()

static void testout(out string str)

同樣,在將ref換成out後,會發現最後的輸出仍然是相同的,那這兩個關鍵字的區別是什麼呢?

進一步測試:

ref:

static void testrefandout()

static void testref(ref string str)

outstatic void testrefandout()

static void testout(out string str)

ref的那段**順利編譯,輸出"good luck!",而out那段**卻無法通過編譯,提示「use of unassigned out parameter 'str' 」,即使用了未分配位址的out引數str。怎麼回事呢?

原來out引數在進入方法的時候,c#會自動清空它的一切引用和指向,所以在上面的out例子中,必需先要為str引數賦值。如以下程式。

static void testrefandout()

static void testout(out string str)

ok,得到第乙個區別: out 引數在進入方法(函式)時後清空自己,使自己變成乙個乾淨的引數,也因為這個原因必須在方法返回之前或再使用out引數前為 out 引數賦值(只有位址沒有值的引數是不能被.net接受的);而ref引數是不需要在被呼叫方法使用前先賦值的,甚至也可以被呼叫方法中不改變ref引數的值,這都不會引起編譯錯誤。

在繼續看一段**:

ref:

static void testrefandout()

static void testref(ref string str)

out:

static void testrefandout()

static void testout(out string str)

這回發現,ref這段**無法編譯了,s1是乙個空引用,所以無法使用。而out引數則因為上述的那個原因,它不在乎s1是不是空引用,因為就算s1不是空引用,它也會把s1變成空引用的。

ok,第二個區別:ref引數在使用前必需初始化,而out不需要。

嗯,由上邊兩個區別可以引申一下,out引數只進不出,ref引數有進有出。在用法上概括一下就是:out適合用在需要retrun多個返回值的地方,而ref則用在需要被呼叫的方法修改呼叫者的引用的時候。

一點資料:

注:在c#中,方法的引數傳遞有四種型別:傳值(by value),傳址(by reference),輸出引數(by output),陣列引數(by array)。傳值引數無需額外的修飾符,傳址引數需要修飾符ref,輸出引數需要修飾符out,陣列引數需要修飾符params。傳值引數在方法呼叫過 程中如果改變了引數的值,那麼傳入方法的引數在方法呼叫完成以後並不因此而改變,而是保留原來傳入時的值。傳址引數恰恰相反,如果方法呼叫過程改變了引數 的值,那麼傳入方法的引數在呼叫完成以後也隨之改變。實際上從名稱上我們可以清楚地看出兩者的含義--傳值引數傳遞的是呼叫引數的乙份拷貝,而傳址引數傳 遞的是呼叫引數的記憶體位址,該引數在方法內外指向的是同乙個儲存位置。

上邊的就是這兩個引數在應用上的區別,希望對大家有用!

C 中ref與out 關鍵字的區別

首先,我們都知道,ref和out關鍵字生命的引數都是傳址的,那麼二者有區別嗎?使用ref關鍵字時,引數必須先初始化,而out關鍵字則不需要,out關鍵在宣告的關鍵字,在函式中必須被初始化,用 來說明.public void use int t 100 int k refmethod ref t 注意...

c 中關鍵字ref與out的區別

一 關鍵字ref的使用 static void main string args private static void change string temp private static void changebyref ref string temp 輸出結果 aa refchanged 在ch...

C 中關鍵字ref與out的區別

總的來說,通常我們向方法中傳遞的是值.方法獲得的是這些值的乙個拷貝,然後使用這些拷貝,當方法執行完畢後,這些拷貝將被丟棄,而原來的值不將受到影響.此外我們還有其他向方法傳遞引數的形式,引用 ref 和輸出 out 有時,我們需要改變原來變數中的值,這時,我們可以向方法傳遞變數的引用,而不是變數的值....