2、過(guò)程參數(shù)傳遞
過(guò)程通常需要某些程序當(dāng)前狀態(tài)的信息才能完成它的工作。程序當(dāng)前狀態(tài)信息也包含在調(diào)用過(guò)程時(shí)傳遞到過(guò)程內(nèi)的變量。當(dāng)將變量傳遞到過(guò)程時(shí)(完成形式參數(shù)與實(shí)際參數(shù)的結(jié)合),稱變量為參數(shù)。
(1)參數(shù)的數(shù)據(jù)類型
過(guò)程的參數(shù)類型缺省為Variant數(shù)據(jù)類型。不過(guò),也可以聲明參數(shù)為其它數(shù)據(jù)類型。例如:函數(shù)接受一個(gè)字符串變量和一個(gè)整型變量:
Function WhatForLunch(WeekDay As String,Hour As Integer) As String
If WeekDay="Saturday" then
WhatForLunch="Fish"
ELse
WhatForLunch="Chicken"
End If
If Hour>2 Then WhatForLunch="Sorry,It's too late!"
End Function
(2)按地址傳遞參數(shù)
按地址傳遞參數(shù)過(guò)程(也稱“引用”)使得過(guò)程通過(guò)變量的內(nèi)存地址去訪問(wèn)實(shí)際變量的內(nèi)容。將變量傳遞給過(guò)程時(shí),在過(guò)程中可改變變量的值。按地址傳遞參數(shù)在VB中是缺省的。
如果給按地址傳遞的參數(shù)指定數(shù)據(jù)類型,就必須將這種類型的值傳遞給參數(shù),也可以給參數(shù)傳遞一個(gè)表達(dá)式,VB計(jì)算表達(dá)式,并按要求的類型將值傳遞給參數(shù)。
當(dāng)變量通過(guò)地址傳遞時(shí),對(duì)變量的任何修改都被傳遞給調(diào)用過(guò)程。傳址參數(shù)調(diào)用在修改調(diào)用過(guò)程中的變量方面具有顯著的優(yōu)點(diǎn),只是不要在過(guò)程中無(wú)意地修改變量。
例如,下面的子過(guò)程聲明和調(diào)用:
Sub CostPlusInterest(Cost,Total)
Cost=Cost*1.05 'add 5% to Cost
Total=Int(Cost) 'then make integer and return
End Sub
調(diào)用:
……
Price=100
Total=0
Costplusinterest Price,Total
Print Price; "at 5% interest is ";Total
本例中,程序?qū)蓚€(gè)傳址變量傳遞給CostPlusInterest過(guò)程:Price和Total。程序員計(jì)劃在隨后的Print方法中使用更新的Total變量,但不慎忘掉了Price變量在過(guò)程的中間步驟中被更新,所以程序運(yùn)行時(shí),產(chǎn)生結(jié)果如下:
105 at 5% interest is 105
沒(méi)有達(dá)到預(yù)期的效果。
(3)按值傳遞參數(shù)
避免上述問(wèn)題的一種好的做法是按值傳遞參數(shù)。按值傳遞參數(shù)傳遞的只是變量的副本。如果過(guò)程執(zhí)行過(guò)程中改變了這個(gè)值,則所有變動(dòng)只影響副本而不會(huì)影響變量本身。使用ByVal關(guān)鍵字指出參數(shù)是按值來(lái)傳遞的。
例如:對(duì)上例加以修改,就不會(huì)發(fā)生上面出現(xiàn)的錯(cuò)誤,改動(dòng)如下:
Sub CostPlusInterest(ByVal Cost,Total)
當(dāng)使用ByVal聲明Cost參數(shù)時(shí),就會(huì)產(chǎn)生正確的結(jié)果:
100 at 5% interest is 105
如果不想依賴于ByVal關(guān)鍵字,也可以換一種方法防止所傳遞的變量被修改:將變量置于括弧內(nèi)而把它轉(zhuǎn)換為文字值,如上例中,調(diào)用costplusinterest過(guò)程的語(yǔ)句為:
costplusinterest(price),total,
同樣可以得到正確結(jié)果。
再例如,有下面代碼:
Option Explicit
Function Multiply(ByVal n As Integer) As Integer
Multiply = 1
Do While n > 0
Multiply = Multiply * n '求n!
n = n - 1
Loop
End Function
Private Sub Form_Click()
Dim sum As Integer, i As Integer
For i = 5 To 1 Step -1
sum = sum + Multiply(i)
Next
Print "sum="; sum
End Sub
運(yùn)行后結(jié)果為153(5!+4!+3!+2!+1?。?BR> 若將函數(shù)的參數(shù)n前的“ByVal”去掉,結(jié)果為120(5?。?,這顯然不是編者的初衷,是錯(cuò)誤的。
究竟什么時(shí)候用傳值方式,什么時(shí)候用傳地址方式,沒(méi)有硬性規(guī)定。下面幾條規(guī)則可供參考:
1)對(duì)于整形、長(zhǎng)整形或單精度參數(shù),如果不希望過(guò)程修改實(shí)參的值,則應(yīng)加上關(guān)鍵字ByVal(按值傳送)。而為了提高效率,字符串和數(shù)組應(yīng)通過(guò)地址傳送。此外,用戶定義的類型(記錄類型)和控件只能通過(guò)地址傳送。
2)對(duì)于其它數(shù)據(jù)類型,包括雙精度型、貨幣型和變體數(shù)據(jù)類型,可以用兩種方式傳送。但經(jīng)驗(yàn)證明,此類參數(shù)用傳值方式傳送,這樣可以避免錯(cuò)用參數(shù)。
3)如果沒(méi)有把握,用傳值方式傳送所有變量(字符串、數(shù)組和記錄類型變量除外),在編寫完程序并能正確運(yùn)行后,再把部分參數(shù)改為傳地址,以加快運(yùn)行速度。這樣,即使在刪除一些ByVal后,程序不能正確運(yùn)行,也很容易查出錯(cuò)在什么地方。
(4)使用可選的參數(shù)
VB提供了十分靈活和安全的參數(shù)傳送方式,允許使用可選參數(shù)和可變參數(shù)。在調(diào)用一個(gè)過(guò)程時(shí),可以向過(guò)程傳送可選的參數(shù)或者任意數(shù)量的參數(shù)。
在前面的例子中,一個(gè)過(guò)程的形式參數(shù)(形參)是固定的,調(diào)用時(shí)提供的實(shí)際參數(shù)(實(shí)參)也是固定的。也就是說(shuō),如果一個(gè)過(guò)程有三個(gè)形參,則調(diào)用時(shí)必須按相同的順序和類型提供三個(gè)實(shí)參。
在VB中,可以指定一個(gè)或多個(gè)參數(shù)作為可選參數(shù)。例如,我們建立一個(gè)計(jì)算兩個(gè)數(shù)的乘積的過(guò)程,它能夠有選擇的乘以第三個(gè)數(shù)。在調(diào)用時(shí),既可以給它傳送兩個(gè)參數(shù),也可以給它傳送三個(gè)參數(shù)。
過(guò)程通常需要某些程序當(dāng)前狀態(tài)的信息才能完成它的工作。程序當(dāng)前狀態(tài)信息也包含在調(diào)用過(guò)程時(shí)傳遞到過(guò)程內(nèi)的變量。當(dāng)將變量傳遞到過(guò)程時(shí)(完成形式參數(shù)與實(shí)際參數(shù)的結(jié)合),稱變量為參數(shù)。
(1)參數(shù)的數(shù)據(jù)類型
過(guò)程的參數(shù)類型缺省為Variant數(shù)據(jù)類型。不過(guò),也可以聲明參數(shù)為其它數(shù)據(jù)類型。例如:函數(shù)接受一個(gè)字符串變量和一個(gè)整型變量:
Function WhatForLunch(WeekDay As String,Hour As Integer) As String
If WeekDay="Saturday" then
WhatForLunch="Fish"
ELse
WhatForLunch="Chicken"
End If
If Hour>2 Then WhatForLunch="Sorry,It's too late!"
End Function
(2)按地址傳遞參數(shù)
按地址傳遞參數(shù)過(guò)程(也稱“引用”)使得過(guò)程通過(guò)變量的內(nèi)存地址去訪問(wèn)實(shí)際變量的內(nèi)容。將變量傳遞給過(guò)程時(shí),在過(guò)程中可改變變量的值。按地址傳遞參數(shù)在VB中是缺省的。
如果給按地址傳遞的參數(shù)指定數(shù)據(jù)類型,就必須將這種類型的值傳遞給參數(shù),也可以給參數(shù)傳遞一個(gè)表達(dá)式,VB計(jì)算表達(dá)式,并按要求的類型將值傳遞給參數(shù)。
當(dāng)變量通過(guò)地址傳遞時(shí),對(duì)變量的任何修改都被傳遞給調(diào)用過(guò)程。傳址參數(shù)調(diào)用在修改調(diào)用過(guò)程中的變量方面具有顯著的優(yōu)點(diǎn),只是不要在過(guò)程中無(wú)意地修改變量。
例如,下面的子過(guò)程聲明和調(diào)用:
Sub CostPlusInterest(Cost,Total)
Cost=Cost*1.05 'add 5% to Cost
Total=Int(Cost) 'then make integer and return
End Sub
調(diào)用:
……
Price=100
Total=0
Costplusinterest Price,Total
Print Price; "at 5% interest is ";Total
本例中,程序?qū)蓚€(gè)傳址變量傳遞給CostPlusInterest過(guò)程:Price和Total。程序員計(jì)劃在隨后的Print方法中使用更新的Total變量,但不慎忘掉了Price變量在過(guò)程的中間步驟中被更新,所以程序運(yùn)行時(shí),產(chǎn)生結(jié)果如下:
105 at 5% interest is 105
沒(méi)有達(dá)到預(yù)期的效果。
(3)按值傳遞參數(shù)
避免上述問(wèn)題的一種好的做法是按值傳遞參數(shù)。按值傳遞參數(shù)傳遞的只是變量的副本。如果過(guò)程執(zhí)行過(guò)程中改變了這個(gè)值,則所有變動(dòng)只影響副本而不會(huì)影響變量本身。使用ByVal關(guān)鍵字指出參數(shù)是按值來(lái)傳遞的。
例如:對(duì)上例加以修改,就不會(huì)發(fā)生上面出現(xiàn)的錯(cuò)誤,改動(dòng)如下:
Sub CostPlusInterest(ByVal Cost,Total)
當(dāng)使用ByVal聲明Cost參數(shù)時(shí),就會(huì)產(chǎn)生正確的結(jié)果:
100 at 5% interest is 105
如果不想依賴于ByVal關(guān)鍵字,也可以換一種方法防止所傳遞的變量被修改:將變量置于括弧內(nèi)而把它轉(zhuǎn)換為文字值,如上例中,調(diào)用costplusinterest過(guò)程的語(yǔ)句為:
costplusinterest(price),total,
同樣可以得到正確結(jié)果。
再例如,有下面代碼:
Option Explicit
Function Multiply(ByVal n As Integer) As Integer
Multiply = 1
Do While n > 0
Multiply = Multiply * n '求n!
n = n - 1
Loop
End Function
Private Sub Form_Click()
Dim sum As Integer, i As Integer
For i = 5 To 1 Step -1
sum = sum + Multiply(i)
Next
Print "sum="; sum
End Sub
運(yùn)行后結(jié)果為153(5!+4!+3!+2!+1?。?BR> 若將函數(shù)的參數(shù)n前的“ByVal”去掉,結(jié)果為120(5?。?,這顯然不是編者的初衷,是錯(cuò)誤的。
究竟什么時(shí)候用傳值方式,什么時(shí)候用傳地址方式,沒(méi)有硬性規(guī)定。下面幾條規(guī)則可供參考:
1)對(duì)于整形、長(zhǎng)整形或單精度參數(shù),如果不希望過(guò)程修改實(shí)參的值,則應(yīng)加上關(guān)鍵字ByVal(按值傳送)。而為了提高效率,字符串和數(shù)組應(yīng)通過(guò)地址傳送。此外,用戶定義的類型(記錄類型)和控件只能通過(guò)地址傳送。
2)對(duì)于其它數(shù)據(jù)類型,包括雙精度型、貨幣型和變體數(shù)據(jù)類型,可以用兩種方式傳送。但經(jīng)驗(yàn)證明,此類參數(shù)用傳值方式傳送,這樣可以避免錯(cuò)用參數(shù)。
3)如果沒(méi)有把握,用傳值方式傳送所有變量(字符串、數(shù)組和記錄類型變量除外),在編寫完程序并能正確運(yùn)行后,再把部分參數(shù)改為傳地址,以加快運(yùn)行速度。這樣,即使在刪除一些ByVal后,程序不能正確運(yùn)行,也很容易查出錯(cuò)在什么地方。
(4)使用可選的參數(shù)
VB提供了十分靈活和安全的參數(shù)傳送方式,允許使用可選參數(shù)和可變參數(shù)。在調(diào)用一個(gè)過(guò)程時(shí),可以向過(guò)程傳送可選的參數(shù)或者任意數(shù)量的參數(shù)。
在前面的例子中,一個(gè)過(guò)程的形式參數(shù)(形參)是固定的,調(diào)用時(shí)提供的實(shí)際參數(shù)(實(shí)參)也是固定的。也就是說(shuō),如果一個(gè)過(guò)程有三個(gè)形參,則調(diào)用時(shí)必須按相同的順序和類型提供三個(gè)實(shí)參。
在VB中,可以指定一個(gè)或多個(gè)參數(shù)作為可選參數(shù)。例如,我們建立一個(gè)計(jì)算兩個(gè)數(shù)的乘積的過(guò)程,它能夠有選擇的乘以第三個(gè)數(shù)。在調(diào)用時(shí),既可以給它傳送兩個(gè)參數(shù),也可以給它傳送三個(gè)參數(shù)。