c#函數(shù)參數(shù)有四種類型媳禁,分別是:值參數(shù)、引用參數(shù)画切、輸出參數(shù)竣稽、參數(shù)數(shù)組
在了解函數(shù)的參數(shù)之前,我們先來(lái)了解什么是實(shí)參和形參霍弹。
什么是形參毫别?
????????形參是聲明在方法的參數(shù)列表中,他可以是不同類型的典格,中間用逗號(hào)隔開(kāi)
什么是實(shí)參岛宦?
? ? ? ? 當(dāng)調(diào)用一個(gè)方法時(shí),用于初始化形參的表達(dá)式或變量成為實(shí)參钝计,他放在方法調(diào)用的參數(shù)列表中(注:他可以是表達(dá)式)
調(diào)用方法時(shí)恋博,必須滿足以下要求:
? ??????● 實(shí)參的數(shù)目必須和形參數(shù)目相同(參數(shù)數(shù)組除外)
? ??????●每個(gè)實(shí)參必須和相應(yīng)的形參類型匹配
1.值參數(shù)
什么是值參數(shù)?
? ? ? ? 通俗的講私恬,沒(méi)有用到ref,out炼吴,param等修飾符本鸣,形式是類型+參數(shù)名的參數(shù)。
? ? ? ? ?書(shū)上解釋:有幾種參數(shù)硅蹦,他們使用稍微不同的方法從方法傳入或傳出數(shù)據(jù)荣德。你到現(xiàn)在一直看到的這種類型是默認(rèn)的類型闷煤,成為值參數(shù)
特點(diǎn):
? ? ? ? 使用值參數(shù),數(shù)據(jù)通過(guò)復(fù)制到實(shí)參的值到形參的方式傳遞到方法涮瞻。方法被調(diào)用時(shí)鲤拿,系統(tǒng)做如下操作:
? ??????● 在棧中為形參分配空間。
? ??????● 復(fù)制實(shí)參到形參
下面來(lái)看這樣一個(gè)實(shí)例
問(wèn)題:為什么在MyFunc方法之f1和f2同樣加了5署咽,但是a1的val值變了近顷,a2的值卻沒(méi)有變?
我們通過(guò)堆棧來(lái)分析:
? ? ? ? 1.在方法被調(diào)用前宁否,用作實(shí)參的變量a1和a2都已經(jīng)在棧里了窒升。
? ? ? ? 2.隨著方法的開(kāi)始,系統(tǒng)在棧中為形參分配空間慕匠,并把實(shí)參的值復(fù)制給形參饱须。
? ??????????????● 因?yàn)閍1是引用類型的,所以引用被復(fù)制台谊,所以實(shí)參和形參都引用堆中的唯一對(duì)象(f1和a1)蓉媳。
? ??????????????● 因?yàn)閍2是值類型的,所以值被復(fù)制锅铅,產(chǎn)生了一個(gè)獨(dú)立的數(shù)據(jù)督怜。
? ? ? ? ?3.在方法的結(jié)尾,f2和對(duì)象f1的字段都被加上了5狠角。
? ? ? ? ?4.方法執(zhí)行后号杠,形參從棧中彈出。
? ??????????????●a2丰歌,值類型姨蟋,他的值沒(méi)有受方法的影響。
? ??????????????●a1立帖,引用類型眼溶,因?yàn)樗托螀1指向同一塊地址,所以隨著f1改變晓勇,他的值一? ? ? ? ? ????????????????塊跟著改變了堂飞。
2.引用參數(shù)ref
什么是引用參數(shù)?
? ? ? ? 通俗的講绑咱,在參數(shù)類型前加上ref修飾符的參數(shù)
特點(diǎn):
? ??????● 必須在方法聲明和調(diào)用中都使用ref修飾符
? ? ? ??● 實(shí)參必須是變量绰筛,在用作實(shí)參前必須被賦值,否則會(huì)報(bào)錯(cuò)描融,如果是引用類型變量铝噩,可以賦值為一個(gè)應(yīng)用或者null
? ??????● 和值參數(shù)不同,不在棧中為形參分配新的內(nèi)存
? ? ? ??●形參的名稱相當(dāng)于實(shí)參變量的別名窿克,引用于實(shí)參相同的內(nèi)存位置
下面來(lái)看這樣一個(gè)實(shí)例
問(wèn)題:為什么這次a1和a2的值最終改變了骏庸?
同樣的毛甲,我們通過(guò)堆棧來(lái)分析
1.在方法調(diào)用之前,實(shí)參變量a1和a2都已經(jīng)在棧里了
2. 在方法開(kāi)始之前具被。形參名被設(shè)置為實(shí)參的別名玻募。變量a1和f1都指向了堆中相同的內(nèi)存地址,f2和a2都使用了棧中同一塊內(nèi)存
3.在方法結(jié)束位置一姿,f2和f1都加上了5
4.方法結(jié)束后七咧,形參的名稱已經(jīng)失效,但是a2的值和a1指向的對(duì)象的值都在方法內(nèi)部被改變了啸蜜。a2是值類型的變量坑雅,a1是引用類型
3.輸出參數(shù)out
什么是輸出參數(shù)?
? ? ? ? 通俗的講衬横,在參數(shù)面前加上out修飾符的參數(shù)
? ? ? ? 輸出參數(shù)用于從方法體內(nèi)吧數(shù)據(jù)傳出到調(diào)用代碼裹粤。
特點(diǎn):
? ??????● 必須在聲明的調(diào)用中都使用out修飾符
? ??????● 實(shí)參必須是變量,而不能是其他表達(dá)式
? ??????● 形參相當(dāng)于實(shí)參的別名蜂林,形參和實(shí)參都是統(tǒng)一內(nèi)存位置的名稱
? ? ? ??
與ref參數(shù)的不同點(diǎn)
? ??????● 在方法內(nèi)部遥诉,輸入?yún)?shù)在被讀取之前必須被賦值。這意味著與參數(shù)的初始值是無(wú)關(guān)的噪叙,所以沒(méi)有必要在方法調(diào)用之前為實(shí)參賦值矮锈。
? ??????● 每個(gè)輸出參數(shù)在方法返回之前必須被賦值,否則會(huì)被報(bào)錯(cuò)
下面來(lái)看這樣一個(gè)示例
可以看到睁蕾,和引用參數(shù)一樣苞笨,a1 a2的值最后都變了
我們通過(guò)堆棧來(lái)分析
1. 在方法調(diào)用之前,將要被用作實(shí)參的變量a1和a2都已經(jīng)在棧里了子眶。
2.在方法的開(kāi)始瀑凝,形參名被設(shè)置為實(shí)參的別名,變量a1和f1都指向了堆中相同的內(nèi)存地? ? ? 址臭杰,f2和a2都使用了棧中同一塊內(nèi)存
3.在方法內(nèi)部粤咪,創(chuàng)建了一個(gè)MyClass類型的對(duì)象并把它賦值給f1,然后賦一個(gè)值給f1的字段渴杆,也賦一個(gè)值給f2寥枝。對(duì)f1和f1賦值時(shí)必須的,因?yàn)樗麄兪禽敵鰠?shù)
4.方法結(jié)束后磁奖,形參的名稱已經(jīng)失效囊拜,但是a2的值和a1指向的對(duì)象的值都在方法內(nèi)部被改變了。
4.參數(shù)數(shù)組params
什么是參數(shù)數(shù)組点寥?
????????簡(jiǎn)單的說(shuō)就是 params + 參數(shù)類型 + [ ] + 參數(shù)名? ? ? 的參數(shù)形式艾疟,它允許多個(gè)或者0個(gè)實(shí)參對(duì)應(yīng)一個(gè)特殊的形參。
特點(diǎn):
? ??????● 在一個(gè)參數(shù)列表中只能有一個(gè)參數(shù)數(shù)組敢辩。
? ??????● 如果有蔽莱,他必須是列表中的最后一個(gè)。
? ??????● 在數(shù)據(jù)類型前面用params修飾符
? ??????● 在數(shù)據(jù)類型后放置一組空的方括號(hào)
? ??????● 實(shí)參可以為0
如何調(diào)用戚长?
? ??????● 用一個(gè)逗號(hào)分割該數(shù)據(jù)類型元素的列表盗冷。所有元素必須是方法聲明中指定的類型。
? ??????● 一個(gè)該數(shù)據(jù)類型元素的一維數(shù)組
1.數(shù)組分離作實(shí)參
? 可以看到雖然在方法內(nèi)部修改了參數(shù)的值同廉,但是打印出來(lái)實(shí)參的值并沒(méi)有改變
用堆棧解釋
? ??????● 在方法調(diào)用之前仪糖,三個(gè)實(shí)參就已經(jīng)在棧里
? ? ? ??● 在方法開(kāi)始的時(shí)候,在棧中新加入形參inVals迫肖,三個(gè)實(shí)參被用于初始化堆中的數(shù)組锅劝,在并且數(shù)組的引用被賦值給形參inVals
? ??????● 在方法內(nèi)部,代碼首先檢查以確認(rèn)數(shù)組醫(yī)用不是null蟆湖,然后處理數(shù)組故爵,把每個(gè)元素乘10并保存回去
? ??????● 方法執(zhí)行之后,形參invals失效
注意:
? ? ? ??● 如果數(shù)組參數(shù)是值類型隅津,那么值被復(fù)制诬垂,實(shí)參不收方法內(nèi)部的影響
? ??????● 如果數(shù)組參數(shù)是引用類型,那么引用被復(fù)制伦仍,實(shí)參引用的對(duì)象可以受到方法內(nèi)部的影響
2.數(shù)組作實(shí)參
? ? ? ? 把單一的數(shù)組變量作為實(shí)參傳遞结窘,這種情況下,編譯器使用你的數(shù)組而不是重新創(chuàng)建一個(gè)