VB考試教程:過(guò)程的使用之過(guò)程參數(shù)傳遞

字號(hào):

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ù)。