对函数的递归调用是否实例化它?
Does a recursive call to a function instantiate it?
我正在尝试理解下面用于计数的代码片段
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
正如@EdPlunkett 提到的,实例化 与它无关。这涉及创建新对象。这是关于从自身内部调用相同的函数,或 recursion.
程序执行如下:
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 个空格以显示递归调用或退出。
如您所见,在执行第一个 MsgBox
之前,调用堆栈增加到完整的 9 级深度(由于 If (n > 1)
)。然后代码 return 返回到前一个调用者,后者调用它的 MsgBox
并继续整个过程返回调用堆栈,return 返回到每个先前的调用者。
最后,我们return回到countup(10)
,执行最后的MsgBox(10),此时我们return到myprogram()
.
程序首先调用您的 subroutine/function countup
并传入值 10。然后该值位于作为 [=10= 的参数的变量 n
中].该函数测试 n
的值并使用 n - 1
再次调用 countup
(第一次调用 countup
时为 9)。 countup
不断被调用,越来越深,n - 1
直到我们降到 1。然后我们开始解开。要解开的最深层收到 n
,其中包含 1,因此它会调用 MsgBox (n)
,显示 1。当我们解开到下一层时,n = 2
显示 MsgBox
2.以此类推,一直往回栈。
将参数传递给 countup(n As Integer)
这样的过程实际上是 countup(byRef n As Integer)
的简短版本。如果您在您的 sub 中更改 n
的值,则调用 n
的值也会更改。
虽然我同意 "instantiate" 不是正确的术语,但我认为它可能是一种思考正在发生的事情的有用方式。如果你稍微改变你的 countup 子例程(见下文),它现在也存储它传递的参数,你真的会有多达 10 个名为 "storeN" 的变量实例,每个实例都有不同的值。您只能在 "current" 版本的 countup 中访问 storeN。但是其余的都在那里,并且随着递归展开,将恢复到 "earlier" countup 调用中。
这基本上就是变量 n 发生的情况。有 个不同的 "instances",随着递归的展开,它们又回到了正轨。这也是为什么 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
我正在尝试理解下面用于计数的代码片段
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
正如@EdPlunkett 提到的,实例化 与它无关。这涉及创建新对象。这是关于从自身内部调用相同的函数,或 recursion.
程序执行如下:
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 个空格以显示递归调用或退出。
如您所见,在执行第一个 MsgBox
之前,调用堆栈增加到完整的 9 级深度(由于 If (n > 1)
)。然后代码 return 返回到前一个调用者,后者调用它的 MsgBox
并继续整个过程返回调用堆栈,return 返回到每个先前的调用者。
最后,我们return回到countup(10)
,执行最后的MsgBox(10),此时我们return到myprogram()
.
程序首先调用您的 subroutine/function countup
并传入值 10。然后该值位于作为 [=10= 的参数的变量 n
中].该函数测试 n
的值并使用 n - 1
再次调用 countup
(第一次调用 countup
时为 9)。 countup
不断被调用,越来越深,n - 1
直到我们降到 1。然后我们开始解开。要解开的最深层收到 n
,其中包含 1,因此它会调用 MsgBox (n)
,显示 1。当我们解开到下一层时,n = 2
显示 MsgBox
2.以此类推,一直往回栈。
将参数传递给 countup(n As Integer)
这样的过程实际上是 countup(byRef n As Integer)
的简短版本。如果您在您的 sub 中更改 n
的值,则调用 n
的值也会更改。
虽然我同意 "instantiate" 不是正确的术语,但我认为它可能是一种思考正在发生的事情的有用方式。如果你稍微改变你的 countup 子例程(见下文),它现在也存储它传递的参数,你真的会有多达 10 个名为 "storeN" 的变量实例,每个实例都有不同的值。您只能在 "current" 版本的 countup 中访问 storeN。但是其余的都在那里,并且随着递归展开,将恢复到 "earlier" countup 调用中。
这基本上就是变量 n 发生的情况。有 个不同的 "instances",随着递归的展开,它们又回到了正轨。这也是为什么 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