我想了解下面的代码片段来计算
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
答案 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
的值也会更改。