* 變數根據儲存方式的不同,可以分為:值型別和引用型別,它們之間的區別:
* 值型別在記憶體的乙個地方(堆疊)儲存它們自己和它們的內容
* 引用型別在記憶體的乙個地方(堆)儲存乙個引用,而在另外乙個地方儲存內容。
* 還用引用型別可以為null,而值型別總是包含乙個值,
* 簡單型別中的string和object是引用型別,陣列也是隱式的引用型別。我們建立的每個類也是引用型別。
*//*
無論對於值型別還是引用型別,對其作為函式引數或者返回值的時候,都是容易犯錯的地方,要加以注意,如下:
對於值型別來說,當其作為函式引數時,一般直接操作時不能被修改的
public void increment( int i )
要想在函式中對傳進去的引數做真正的修改,需要借助於ref這個關鍵字,如下
pubic void increment( ref int i )
也就是說在函式中對值型別引數進行修改,必須使用ref或者out關鍵字.
而對於引用型別來說,當其作為函式引數的時候,情況恰恰相反,即不希望在函式中被修改,如下:
public void addvalue( mytype typvalue )
由於對於引用型別來說,其賦值操作只是對原有物件的引用,對其進行修改 就是對原有物件的修改,這是很多情況都部希望發生的.
為了防止這種事的發生,需要給引用型別提供clone函式.clone函式用法比較複雜,以後會單獨去研究一下.我們還是重點關注本
例中ref和out關鍵字的區別和用法吧.
----------------------------------------
ref與out的區別及用法,params關鍵字的用法.
----------------------------------------
ref和out都是c#中的關鍵字,所實現的功能也差不多,都是指定乙個引數按照引用傳遞。對於編譯後的程式而言,它們之間沒有任何區別,也就是說它們只有語法區別。總結起來,他們有如下語法區別:
1、ref傳進去的引數必須在呼叫前初始化,out不必,即:
int i;
somemethod( ref i );//語法錯誤
somemethod( out i );//通過
2、ref傳進去的引數在函式內部可以直接使用,而out不可:
public void somemethod(ref int i)
public void somemethod(out int i)
3、ref傳進去的引數在函式內部可以不被修改,但out必須在離開函式體前進行賦值。
總結:
應該說,系統對ref的限制是更少一些的。out雖然不要求在呼叫前一定要初始化,但是其值在函式內部是不可見的,也就是不能使用通過out傳進來的值,並且一定要賦乙個值。也就是說函式承擔初始化這個變數的責任
兩者都是按位址傳遞的,使用後都將改變原來的數值。
其次:rel可以把引數的數值傳遞進函式,但是out是要把引數清空,就是說你無法把乙個數值從out傳遞進去的,out進去後,引數的數值為空,所以你必須初始化一次。這個就是兩個的區別,或者說就像有的網友說的,rel是有進有出,out是只出不入.
params 是陣列型引數,根據實參形式選擇引用傳遞或值傳遞,包含數量可變的引數。特別注意:使用params引數要檢驗引數是否為null
使用params 關鍵字指定的引數必須是函式定義中最後乙個引數.
*/示例:
using system;
class class1
,number2=",num1,num2);
//用作reg引用變數,需要初始化,num1和num2在經過setvalue處理已經被賦值了。
addone(ref num1);
console.writeline ("number1=,number2=",num1,num2);
//num1-num2再賦值給num1,num2值不變
subtract(ref num1,num2);
console.writeline ("number1=,number2=",num1,num2);
//params引數可以為0個或多個
//sum1=0
sum1 = getsum();
//sum1=6+5=11
sum1 = getsum(num1,num2);
//sum2為out引用,無需初始化
//sum2=6+5=11
getsum(out sum2,num1,num2);
/*下面的語句等同於:
* int intarry = new int;
sum3 = getarraysum(intarry);*/
sum3 = getarraysum( new int);
console.writeline ("sum1=,sum2=,sum3=",sum1,sum2,sum3);
console.readline();
}//i傳引用,實參值將在方法中改變
public static void addone(ref int i)
//i傳引用,實參值將改變,j傳值,實參值不變
public static void subtract(ref int i, int j)
//i值out引用,實參值等於方法中i運算結果
public static void setvalue (out int i, int j)
//iarray表示多個int型引數,傳值
//引數中使用params關鍵字,則該函式的引數個數是可變的,利於函式的過載。
public static int getsum ( params int iarray)
return (sum);
}//sum為out引用引數,iarray表示多個int型值引數
//getsum的過載
public static void getsum (out int sum, params int iarray)
}//陣列int為值引數
public static int getarraysum(int iarray)
return sum;}}
}
c 函式引數
如果函式要使用引數,則必須宣告接受引數值的變數,這些變數稱為函式的形式引數 形式引數就像函式內的其他區域性變數,在進入函式時被建立,退出函式時被銷毀 當呼叫函式時,有三種向函式傳遞引數的方式 傳值呼叫 該方法把引數的實際值複製給函式的形式引數,在這種情況下,修改函式的形式引數對實際引數沒有影響 預設...
C 函式引數
函式傳遞的是方法外的變數的副本,函式內的變數變化,不會影響函式外部的變數 static void main string args static void add int a 當引用型別的變數傳入函式後,在方法內部重新給引數賦值,外部變數和內部引數相互之間不會影響,這種情況一般很少見。static ...
C 函式引數
指標呼叫 向函式傳遞引數的指標呼叫方法,把引數的位址複製給形式引數。在函式內,該位址用於訪問呼叫中要用到的實際引數。這意味著,修改形式引數會影響實際引數。include using namespace std void swap int a,int b intmain 執行結果 引用呼叫 該方法把引...