2012-04-21 145 views
11

我在VB6中努力理解按值傳遞並通過引用。我在面向對象的編程語言(如.NET和Java)中完全理解了這些概念(我意識到Java沒有引用)。看看下面的代碼:VB6按值傳遞並通過引用

Private Sub Form_Load() 

Dim Test As Integer 
Test = 1 
TestFunction Test 'line 5 
MsgBox (Test) 

End Sub 

Private Sub TestFunction(ByVal i As Integer) 
    i = i + 1 
End Sub 

消息框打印1,因爲我期望的那樣。如果我在第5行中放上括號測試,那麼消息框會按我的預期打印1。現在看看下面的代碼:

Private Sub Form_Load() 

Dim Test As Integer 
Test = 1 
TestFunction Test 'line 5 
MsgBox Test 

End Sub 

Private Sub TestFunction(ByRef i As Integer) 
    i = i + 1 
End Sub 

消息框打印2,如我所料。但是,如果您將括號添加到第5行,那麼消息框會打印1,因爲我不期望。看起來調用函數可以通過值傳遞,即使被調用函數中定義的變量是ByRef。看起來情況並非如此,即如果被調用的函數具有變量定義爲ByVal的簽名,則它總是ByVal(即使調用函數中的變量周圍沒有括號)。 VB6背後的想法是什麼?我意識到這是VB6中的一個基本問題,但它讓我感到困惑。我已閱讀MSDN文檔,並意識到這是全部真實的,但它並沒有解釋它背後的想法。

回答

16

這是VB6中的一個經典問題。它是explained in the VB6 manual。在下面這個代碼,VB6對待參數作爲表達(試驗),而不是一個可變參考

TestFunction (Test) 

爲了傳遞給變量的引用要麼省略托架或使用傳統Call statement(要求括號內)

TestFunction Test 
Call TestFunction(Test) 

VB6讓你表情傳遞給ByRef參數,即使該方法改變它們。例如,您可以編寫

TestFunction (Test + 2) 

編譯器創建一個臨時副本並通過引用傳遞該副本。 VB.Net uses brackets in a similar way

你也可以讓編譯器創建臨時副本,如果TestFunction需要兩個參數是這樣的:

TestFunction (one), (two) 

如果你雙倍的支架,你可以得到即使Call臨時副本,增加額外的不必要的對:

Call TestFunction((Test)) 
+0

謝謝。這很有用。 Call函數的用途是什麼?這是否意味着通過的變量永遠不會被視爲表達式?我很驚訝,因爲我從來沒有真正想過。另外,如果有多個變量可以通過,那麼我認爲你不能包含表達式? – w0051977 2012-04-21 20:34:23

+2

我不確定這是一個「陷阱」,因爲它是有記錄的,故意的行爲。 Call關鍵字是遺留的,並且已被棄用,可以回溯到早期的MS Basics。它在那裏可以輕鬆移植舊程序。 – Bob77 2012-04-22 03:56:17

+2

無論參數是否被視爲表達式,「調用」關鍵字都沒有影響。它只是使用圓括號作爲傳遞參數的方式,因此一對括號具有不同的含義。但是參數周圍的括號會產生一個表達式,就像沒有「調用」關鍵字一樣。 – 2012-04-23 14:02:03

6

圓括號內的任何表達導致該要計算的表達式第一做別的之前,即使當表達式僅僅是一個單一可變。在你的情況下,該表達式的結果然後作爲參數傳遞。

所以,你實際上通過引用來傳遞參數。但是你傳遞的參數是表達式的結果而不是原始變量。這就是爲什麼原始變量沒有得到更新。