2014-09-25 128 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變量具有的值。