对函数的递归调用是否实例化它?

时间:2016-04-20 03:56:42

标签: vba excel-vba recursion callstack excel

我想了解下面的代码片段来计算 msgbox如何存储n?

的所有值

是否因为在调用countup(n-1)时,它会实例化该函数,然后将n值与msgbox实例相关联?

Option Explicit

Sub countup(n As Integer)   
   If (n > 1) Then
      countup (n - 1)
   End If
   MsgBox (n)
End Sub

Sub myprogram()
   Call countup(10)
End Sub

4 个答案:

答案 0 :(得分:3)

正如@EdPlunkett所提到的, instantiation 与它无关。这涉及创建新对象。这是关于从内部调用相同的函数,或递归

程序执行如下:

countup(10) called
  -> countup(9) called
    -> countup(8) called
       -> countup(7) called
          -> countup(6) called
            -> countup(5) called
              -> countup(4) called
                ->countup(3) called
                  ->countup(2) called
                     -> MsgBox (1)
                  -> MsgBox (2)
                -> MsgBox (3)
              -> MsgBox (4)
            -> MsgBox (5)
          -> MsgBox (6)
        -> MsgBox (7)
      -> MsgBox (8)
    -> MsgBox (9)
  -> MsgBox (10)

每次缩进2个空格以显示递归调用或退出。

正如您所看到的,在执行第一个If (n > 1)之前,调用堆栈会增加到完整的9级深度(由于MsgBox)。然后代码返回到前一个调用者,调用者调用其MsgBox并继续整个回调调用堆栈,返回到每个前一个调用者。

最后,我们返回countup(10),执行最终的MsgBox(10),此时我们返回myprogram()

答案 1 :(得分:1)

程序首先调用子例程/函数countup并传入值10.然后,该值将作为n的参数变量countup。该函数测试n的值并再次使用countup调用n - 1(第一次调用countup时为9)。 countup随着n - 1越来越深入地被召唤,直到我们降到1.然后我们开始解开。要解析的最深层已收到n,其中包含1,因此它会调用MsgBox (n),显示1.当我们解析到下一级n = 2时,显示MsgBox等等,一直支持堆栈。

答案 2 :(得分:0)

虽然我同意"实例化"不是正确的术语,我认为这可能是思考正在发生的事情的有用方式。如果稍微改变你的countup子程序(见下文),这样它现在也存储了它传递的参数,你真的最多有10个变量实例叫做" storeN&#34 ;,每个实例都有不同的值。您只能访问"当前"中的storeN。计数版。但其余的都在那里,并将恢复到早期"递归的调用,随着递归的展开。

这基本上就是变量n正在发生的事情。 不同的"实例"随着递归的展开,n带回来看日光。这就是为什么MsgBox为每次调用显示不同的n值。

所以我认为你自己的答案基本上是正确的。

Option Explicit

Sub countup(n As Integer)   
   Dim storeN as Integer
   storeN = n
   If (n > 1) Then
      countup (n - 1)
   End If
   MsgBox (n)
End Sub

Sub myprogram()
   Call countup(10)
End Sub

答案 3 :(得分:-1)

将参数移交给像countup(n As Integer)这样的过程实际是countup(byRef n As Integer)的简短版本。如果您更改了子网中n的值,则调用n的值也会更改。