參數按值傳遞和按地址傳遞過程中,指向內存的指針如何變化?

大家好,我們今日繼續講解VBA代碼解決方案的第125講內容:關鍵字ByVal和ByRef的作用。在上一節中我們講到了形式參數和實際參數的定義,同時講到了從實際參數傳遞給形式參數的過程中按值傳遞和按地址傳遞的不同。為了更好的說明按值傳遞和按地址傳遞的區別,我們把上節的程序做一些修正:在函數聲明行去掉參數a前面的關鍵字ByVal,結果會怎樣呢?代碼如下:

Sub MynzNumbers_1()

Dim a As Integer, b As Integer, c As Integer

a = 10

b = 20

c = 30

MsgBox MyAverage_1(a, b, c) & " " & a & " " & b & " " & c

End Sub

Function MyAverage_1(a, ByVal b, ByVal c)

a = a + 60

MyAverage_1 = (a + b + c) / 3

End Function

參數按值傳遞和按地址傳遞過程中,指向內存的指針如何變化?

大家想想這時的結果該是怎麼樣呢?如下面的截圖:

參數按值傳遞和按地址傳遞過程中,指向內存的指針如何變化?

函數的結果仍然相同,但是函數MsgBox顯示的變量a的內容現在是70了。說明這時就改變了儲存在變量a裡的原始數值。

上面的過程如何理解呢?

① 每個要傳遞給函數過程(或子程序)的變量,都可能在接收時改變數值,是否需要保護變量的原始數值是非常重要的。

② VBA有兩個關鍵字,提供是否認可改變變量內容的允許——ByRef和 ByVal,但要注意VBA默認地按地址(關鍵字ByRef)給函數過程(或子程序)傳遞信息,引用函數被調用時,函數參數會按地址傳遞數據。因此,如果函數改變了參數值,原始的數值就被改變了。

③ 在上面的例子中,函數MyAverage_1聲明參數a的前面去掉了關鍵字ByVal時,你就會得到按地址傳遞參數的結果。如果你想要函數過程 改變原始數值,你不必專門在參數前加關鍵字ByRef,因為,變量數值的傳遞默認就是ByRef。

本節的最後我們再談一下按值傳遞的過程是如何進行的,當你在參數名稱前使用關鍵字ByVal時,這意味著VBA複製一份原始數據,然後將複製 值傳遞給函數,如果函數改變了參數的數值的話,原始數據依然不會變——只有複製值變化。這就是為什麼函數MyAverage改變了變量a的數值,而它的原始值還保持不變了。

如果你對上述過程還是不清楚,我再做一個更加形象的說明:

①按址傳遞時,實質上實際參數是把指針(地址)傳遞給形式參數了,這時指針指向的地址的值即是實際參數,此時形式參數與實際參數分別有一個指針,但同時指向同一個地址。

②按數值遞時,實質上實參是把複製後的數值傳遞給形參了,這個時候實際參數和形式參數具有不同的指針,形式參數的指針指向的地址是複製後數值的地址指針,此時實際參數的指針沒有發生改變。

今日內容迴向:

1 按值傳遞和按地址傳遞的關鍵字是什麼?

2 如何理解兩種傳遞過程中的指針不同?


分享到:


相關文章: