【问题标题】:VB6 pass by value and pass by referenceVB6值传递和引用传递
【发布时间】:2012-04-21 19:18:01
【问题描述】:

我很难理解 VB6 中的值传递和引用传递。我在 .NET 和 Java 等面向对象的编程语言中完全理解这些概念(我意识到 Java 没有通过引用传递)。看看下面的代码:

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

当我在第 5 行的 Test 周围加上括号时,消息框会按我的预期打印 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 文档,我意识到这一切都是正确的,但它并没有解释其背后的原因。

【问题讨论】:

    标签: vba vbscript vb6


    【解决方案1】:

    这是 VB6 中的经典问题。它是explained in the VB6 manual。在下面的代码中,VB6 将参数视为表达式(测试)而不是变量引用

    TestFunction (Test)
    

    为了传递对变量的引用,可以省略括号或使用旧版Call statement(需要括号)

    TestFunction Test
    Call TestFunction(Test)
    

    VB6 允许您将表达式传递给ByRef 参数,即使方法更改了它们。比如你可以写

    TestFunction (Test + 2)
    

    编译器创建一个临时副本并通过引用传递它。 VB.Netuses brackets in a similar way.

    如果 TestFunction 采用如下两个参数,您还可以让编译器创建临时副本:

    TestFunction (one), (two)
    

    如果您将括号加倍,即使使用Call,您也可以获得临时副本,添加一个额外的不必要的对:

    Call TestFunction((Test))
    

    【讨论】:

    • 谢谢。这很有用。调用函数的目的是什么?这是否意味着传递的变量永远不会被视为表达式?我对此感到惊讶,因为我以前从未真正考虑过。另外,如果要传递多个变量,那么我假设您不能包含表达式?
    • 我不确定这是一个“陷阱”,因为它是记录在案的故意行为。 Call 关键字是遗留的并且已被弃用,可以追溯到早期的 MS Basics。它可以方便地向前移植旧程序。
    • Call 关键字与参数是否被视为表达式无关。它只是使用括号作为传递参数的方式,因此一对括号具有不同的含义。但是参数周围的括号会产生一个表达式,就像没有 Call 关键字一样。
    • @Bob 我称之为陷阱,因为它是众所周知的语言陷阱,难以理解并且容易陷入新手。这就是我对gotcha的理解。 Mirriam- Webster 词典:gotcha 一个意想不到的通常令人不安的挑战、启示或捕捉。在这种情况下,意图和文档(我已经链接)不足以阻止它成为一个陷阱。
    • @Bob 不,我不相信我的话可以证明任何事情都是陷阱。只有那些经常被误解的东西。我希望我对语言提供一点友好的批评,而不是消极的(我喜欢 VB!)。大多数情况下,虽然我试图通过告诉他们并不是唯一一个发现这困难的学习者来鼓励他们。这在教学中很重要。
    【解决方案2】:

    将任何表达式括在括号中会导致在执行任何其他操作之前先计算该表达式,即使该表达式只是单个变量。在您的情况下,该表达式的结果然后作为参数传递。

    所以,您实际上是通过引用传递参数。但是您传递的参数是表达式的结果,而不是原始变量。这就是为什么原始变量没有得到更新的原因。

    【讨论】:

      猜你喜欢
      • 2014-08-23
      • 2015-05-23
      • 2018-05-27
      • 1970-01-01
      • 2016-01-06
      • 2014-09-14
      • 2014-04-04
      • 1970-01-01
      相关资源
      最近更新 更多