C 語言函式引數的傳遞

2021-04-01 23:44:19 字數 2575 閱讀 6829

c#語言函式引數的傳遞

就像c語言眾多的後世子孫一樣,c#的函式引數是非常講究的。首先,引數必須寫在函式名後面的括號裡,這裡我們有必要稱其為形參。引數必須有乙個引數名稱和明確的型別宣告。該引數名稱只在函式體內部可見。因此在該函式體以外的任何地方使用同樣的變數名是不會引起衝突的。每當呼叫函式的時候,必須將乙個實參傳遞給函式定義中的形參。預設情況下,c#的引數傳遞是值傳遞。這種方式的優點和缺點同樣明顯。另外,在傳送引用型別的時候還時不時引起一些小誤會。更加使人困惑的是,既然clr不支援指標型別,那麼我們以前在c/c++中的那些關於指標傳遞的妙用應該如何實現呢?不必發愁,本文將會逐一回答上述這些疑問。首先我們會討論預設情況下的值傳遞以及這種方式的優缺點,解釋預設情況下傳遞引用型別時容易產生的誤解。然後,我們討論如何利用ref關鍵字把乙個值型別作為引用型別傳遞給引數。最後,我們嘗試著讓乙個函式可以返回多個值,在c/c++中我們經常利用指標達到這一目的,這裡我們將會利用out關鍵字重溫這種美妙的感覺。

值傳遞每當呼叫乙個函式的時候,我們就必須為該函式的每乙個形參傳遞乙個實參。預設情況下,採用值傳遞的機制。也就是說,實參的值會被拷貝到形參裡面,這樣我們在函式內部得到乙個本地變數,該變數的值和傳遞進來的那個實參的值相等,但是它們存放在不同的儲存空間。因此,我們對函式引數所做的一切實際上都是對函式提內本地變數的操作,絕對不會影響到作為實際引數傳遞過來的那個函式體外的變數。看下面的例子,我就不再多費口舌了。

using system;

namespace cs語言函式引數的傳遞

public example()

public void fun1(int parameter)}}

但是值傳遞的機制有乙個明顯的缺點。主要表現在值型別的傳遞方面。我們對引數的修改會在函式體執行結束之際消失。如果我們希望將這種變化影響到作為實參傳遞過來的那個函式體以外的變數就必須把值型別作為引用型別傳遞。後邊會具體討論。值傳遞機制的另乙個缺點,或許你會認為這是乙個優點,表現在引用型別的傳遞方面。按照值傳遞的機制傳遞乙個引用型別的變數,實際上只是完成了一次淺拷貝。請不要誤認為對整個物件進行了深拷貝。函式引數得到的只是實參的handle的值。也就是說,本地的引數實際上只是乙個引用型別的handle,和作為實參傳遞過來的那個變數的handle具有相同的值,指向同乙個object(兩個handle指向堆上的相同位置)。這樣我們在函式內部對引數所做的修改會直接影響到堆上的object。當函式結束之後,本地的引數消失,而對於堆上的object的修改會成為持久的修改而繼續保留下來。

把值型別作為引用型別傳遞

有一些時候,我們不惜望函式對於引數的修改隨著函式的結束而消失。作為引用型別,作到這一點其實一點都不難,就像我們上面說的那樣。但是,如果是值型別的引數,似乎就有一點麻煩了。從前在c/c++裡面可以採取傳遞指標的方法來達到這個目的。但是clr已經明確取消了指標。作為補償,c#為我們提供了ref關鍵字。ref關鍵字通知編譯器,引數的實參是作為引用型別而非值型別進行傳遞。下面的這段程式幫助我們說明問題。

using system;

namespace cs語言函式引數的傳遞

public void fun1(int parameter)

public void fun2(ref int parameter)}}

函式fun2要求乙個int型別的引數,並且伴有關鍵字ref。在main()函式內定義了乙個整形變數argument,它將會作為實參傳遞給函式fun2()。在呼叫該函式之前,首先顯示了變數argument,其值等於5。緊接著呼叫函式fun2(),並且傳遞argument給引數parameter。這時函式得到的是乙個本地的,指向整形變數argument的handle。在函式內部,把parameter加5,然後顯示它。這時其值為10。函式返回後再一次顯示argument,其值同樣為10。

讓函式返回多個返回值

有些時候我們可能會希望乙個函式可以返回多個返回值。事實上,這是不可能的因為乙個函式只能返回乙個返回值。但是我們確實辦法達到這種效果。最簡單的是下面這種方法。

public int fun3(ref int i, int j)

我們這樣呼叫這個函式。

int i;

int sum = exp.fun3(ref i, 10);

system.console.writeline(i);

system.console.writeline(sum);

這樣在執行過函式fun3()之後,我們實際上得到了i的值和i + j的值。實際上起到了利用乙個函式返回兩個值的作用。另外有乙個關鍵字也是非常重要的。那就是out關鍵字。該關鍵字允許向引數傳遞乙個沒有分配空間的引用型別。利用這個關鍵字同樣可以達到返回多個值的目的。

public void fun4(ref int i, out object obj)

上面這個方法要求兩個引數。第二個引數要求乙個object型別的變數。該引數前面有乙個out關鍵字。編譯器會認為該引數的實參沒有被分配儲存空間。out引數在未被賦值之前不能使用。可以這樣呼叫該函式:

int i = 5;

object obj;

exp.fun4(ref i, out obj);

system.console.writeline(i);

system.console.writeline(obj);

輸出為4個10。說明我們在呼叫該函式之後得到了變數i和obj兩個變數的值。

c語言 函式引數的傳遞

程式一 值傳遞 include includeusing namespace std void exchg1 int x,int y int main 原因 函式在呼叫時是隱含地把實參a,b的值分別賦值給了x,y,之後在寫的函式體內再也沒有對a,b進行任何操作了。交換只是x,y變數。並不是a,b。當...

C語言函式引數傳遞的分析

值傳遞,即按值傳遞引數,按值傳遞引數時,是將實參變數的值複製乙個到臨時儲存單元中,如果在呼叫過程中改變了形參的值,不會影響實參變數本身,即實參變數保持呼叫前的值不變。1 形參只能是變數,實參可以是常量 變數或表示式。在被定義的函式中,必須指定形參的型別。2 實參與形參的個數應一樣,型別應一致。字元型...

C語言函式引數的傳遞詳解

開講之前,我先請你做三道題目。嘿嘿,得先把你的頭腦搞昏才行 唉呀,誰扔我雞蛋?考題一,程式 如下 void exchg1 int x,int y main 輸出的結果為 x y a b 問下劃線的部分應是什麼,請完成。考題二,程式 如下 void exchg2 int px,int py main ...