2014-09-25 3 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

Попробуйте выполнить ручную проверку. –

+0

Ну, 5 пройдут и дважды будут печататься ... но между тем, что 4 пройдут и будут печататься дважды ... но между тем, что 3 пройдут и дважды напечатают ...и т. д. – smerny

ответ

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

+0

Я согласен @smerny , это просто читаемость, поэтому я прокомментировал код. –

0

Каждый раз, когда функция re_downandup() называется параметр $num принимает значение, передаваемое в функцию, и она будет держать это значение, пока функция не заканчивается в ее последняя закрывающая скобка.

Также важно понять, что при наличии рекурсивного вызова функции поток выполнения продолжается в этом вызове, поэтому второй print не произойдет, пока выполнение не вернется из указанного рекурсивного вызова.

Так давайте это:

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

Первый print $num напечатает число, то поток выполнение продолжится в новом вызове функции, которая будет отображаться переменной значение минус один. Это будет продолжаться рекурсивно, пока $num не достигнет нуля.

Когда задано условие прерывания рекурсии $num == 0, функция будет «разрешена» для продолжения до конца; поэтому каждый рекурсивный вызов будет возвращен, и тогда начнется выполнение второго print $num, так как это происходит, когда поток выполнения вашей программы возвращается с rec_downandup().

Значение, напечатанное в этом случае, будет независимо от значения, которое имела переменная $num при вызове рекурсивного вызова.

Смежные вопросы