2014-09-25 129 views
1

我想学习递归,并写了一个函数,它需要一个数字并将其计数到零,然后再次将其计数到原始数字,该函数起作用,但我不明白的原因是它为什么会起作用它确实如此。我记住了为什么在else语句之后的第一次打印输出:“5 4 3 2 1”,然后数字是0,if语句输出“0”。在这种情况之后,我不明白,因为现在函数在else语句之后输入第二个打印,并打印出“1 2 3 4 5”,这对我来说很奇怪。如果有人能向我解释这一点,我将不胜感激。为什么这个递归函数像这样工作?

<?php 
function rec_downandup($num){ 
    if($num == 0){ 
     print '0 '; 
    }else{ 
     print $num.' '; 
     rec_downandup($num-1); 
     print $num.' '; 
    } 
} 
rec_downandup(5); 
?> 

输出

5 4 3 2 1 0 1 2 3 4 5 
+0

尝试手动追踪执行。 – 2014-09-25 13:27:46

+0

那么,5将通过并打印两次......但在4之间会通过并打印两次......但在这之间3将通过并打印两次......等 – smerny 2014-09-25 13:28:27

回答

8

当你仔细看看,应该清楚。

print $num.' '; 
rec_downandup($num-1); 
print $num.' '; 

对于你的第一个输入,你会得到

print 5.' '; 
rec_downandup(4); 
print 5.' '; 

,之后把它叫做是

print 5.' '; 
print 4.' '; 
rec_downandup(3); 
print 4.' '; 
print 5.' '; 

所以它出现在功能计数向下和向上,但实际上它只是计数并将每个数字放置两次 - 第二次以相反的顺序排列,因此它似乎在计数。

0

@kingero提供的答案是现货,它解释了究竟发生了什么。如果你想拥有笔直的倒计时,你会做到这一点 -

function rec_downandup($num){ 
    if($num == 0){ 
     print '0 '; 
    }else{ 
     echo $num; 
     $num = rec_downandup($num-1); // you can do this without the variable assignment, it just seems neater this way. 
    } 
} 
rec_downandup(5); 
+0

变量赋值对我来说没有任何意义,函数甚至不会返回任何内容...即使它做到了也不重要,因为范围将尽快过期 – smerny 2014-09-25 13:39:00

+0

我同意@smerny ,它只是一个可读性的东西,这就是为什么我评论了代码。 – 2014-09-25 13:40:35

0

每次re_downandup()函数被调用,参数$num需要传递给函数的值,它会保留该值直到函数结束它最后的大括号。

也很重要的一点是,在递归调用函数的情况下,执行流程将继续进行此调用,这就是为什么第二个print不会发生,直到执行从所述递归调用返回为止。

所以,让我们借此:

print $num.' '; 
rec_downandup($num-1); 
print $num.' '; 

第一print $num将打印数量,则执行流将继续在新的呼叫的功能,这将显示该变量的值减一。这将继续递归地发生,直到$num达到零。

当给出递归中断条件$num == 0时,函数将被“允许”继续,直到结束;所以每次递归调用都会返回,也就是第二个print $num将开始执行,因为当程序的执行流程从rec_downandup()返回时会发生这种情况。

在这种情况下打印的值将是递归调用触发时$num变量具有的值。