使用下面这个简单的测试来递归函数,以理解函数为什么没有正确返回预期值。这是调用程序。
Public Sub TestRecursive()
m_count = 0
Debug.Print Recursive
End Sub
这是递归函数。
Private Function Recursive() As String
Recursive = "start"
m_count = m_count + 1
If m_count < 5 Then
'Debug.Print "counting " & CStr(m_count)
Recursive
Else
'Debug.Print "ended count "
Recursive = "ended"
Exit Function
End If
'Debug.Print "should never reach here"
End Function
不知道发生了什么,但函数递归返回“start”而不是“ends”。有什么想法或建议发生了什么?
答案 0 :(得分:3)
正如zedfoxus所提到的,您看到结果的原因是您的代码没有使用Recursive
的返回值。但是,除非确实需要,否则使用模块范围变量通常是不好的做法。
此版本避免了
Option Explicit
Dim m_count As Long
Public Sub TestRecursive()
m_count = 0
Debug.Print Recursive
End Sub
Private Function Recursive() As String
Recursive = "start"
m_count = m_count + 1
If m_count < 5 Then
'Debug.Print "counting " & CStr(m_count)
Recursive = Recursive() ' <~~~ here's the change!
Else
'Debug.Print "ended count "
Recursive = "ended"
Exit Function
End If
End Function
同样的推理也适用于m_count
变量。这是一个避免这种情况的版本。
Option Explicit
Public Sub TestRecursive()
Dim m_count As Long
m_count = 0
Debug.Print Recursive(m_count)
End Sub
Private Function Recursive(ByRef m_count As Long) As String
Recursive = "start"
m_count = m_count + 1
If m_count < 5 Then
'Debug.Print "counting " & CStr(m_count)
Recursive = Recursive(m_count)
Else
'Debug.Print "ended count "
Recursive = "ended"
Exit Function
End If
End Function
答案 1 :(得分:0)
啊,关于递归的非常有趣的问题。这是你致电Debug.Print Recursive
时发生的事情。这是第一次发生的时间,下面指定为[1]
[1] -> Recursion is "start" -> m_count is 1 -> calls second
[2] -> Recursion is "start" -> m_count is 2 -> calls third
[3] -> Recursion is "start" -> m_count is 3 -> calls fourth
[4] -> Recursion is "start" -> m_count is 4 -> calls fifth
[5] -> Recursion is "start" -> m_count is 5 -> Recursion is "end" -> returns to 4
[4] -> doesn't do anything with returned value -> returns "start" to 3
[3] -> doesn't do anything with returned value -> returns "start" to 2 and so on
因此,您会看到start
已打印。
这是一个稍微修改过的版本,有助于打印ended
。
' make global variables that will remember information
Option Explicit
Dim m_count As Integer
Dim m_finalword As String
Public Sub TestRecursive()
m_count = 0
Recursive ' run recursive here
Debug.Print m_finalword
End Sub
Private Function Recursive() As String
Recursive = "start"
m_count = m_count + 1
If m_count < 5 Then
m_finalword = Recursive ' remember Recursive's value in m_finalword
Recursive ' run recursive again because our count is below 5
Else
m_finalword = "ended" ' if count went above 5, no need to do recursion
Exit Function ' just set m_finalword's value and exit to parent
End If
End Function
您应该检查调试并在VBA中设置断点。在调试此类情况时,它将在未来发挥巨大作用。