2013-08-07 209 views
2

我想知道是否有人可以解釋這個小代碼片段如何工作。遞歸反向函數

void reverse(char *s) 
{ 
    if(*s) 
     reverse(s+1); 
    else 
     return; 

    cout << *s; 
} 

當你調用主這個功能,它理應打印出來放在任何字符串的反轉(即招呼就清點爲2009東海生日賀),但我不明白怎麼。據我瞭解,if語句會增加s的值,直到達到字符串的末尾,並在字符串中打印出每個值。爲什麼不只是重新打印字符串。顯然我錯過了一些東西。 (對不起順便說一句,我是新的C++和遞歸函數)

+4

嘗試手卷的短字符串(「貓」和「狗」彈簧記)通過此功能,並記錄在紙上,一步一個腳印的時候,會發生什麼情況。你可能要先研究指針運算。 – WhozCraig

+2

你可能會絆倒的是該字符串在末尾有一個\ 0,所以'if'語句有一個退出條件。 –

+0

僅供參考你也可以使用std :: reverse –

回答

3

考慮"hello"字符串是如何存儲在內存中:讓我們說其'h'字符的地址恰好是0xC000。那麼字符串的其餘部分將被存儲如下:

0xC000 'h' 
0xC001 'e' 
0xC002 'l' 
0xC003 'l' 
0xC004 'o' 
0xC005 '\0' 

現在考慮一系列reverse調用的:初始調用傳遞0xC000; reverse來自反向內部的呼叫通過s+1,所以下一級獲得0xC001;下一個獲得0xC002,依此類推。

請注意,每個級別調用下一級,直到看到'\0'的級別。在我們開始之前爲零,堆棧「裝」是這樣的:

reverse(0xC004) // the last invocation before we hit '\0' 
reverse(0xC003) 
reverse(0xC002) 
reverse(0xC001) 
reverse(0xC000) // the earliest invocation 

現在當上調用 - reverse(0xC005),爲*s檢查失敗,該函數馬上返回,不打印任何東西。此時堆棧開始「平倉」,無論印刷由其s說法指出:

0xC004 -> prints 'o', then returns to the previous level 
0xC003 -> prints 'l', then returns to the previous level 
0xC002 -> prints 'l', then returns to the previous level 
0xC001 -> prints 'e', then returns to the previous level 
0xC000 -> prints 'h', then returns for good. 

這是原"hello"字符串的反向如何獲取打印。

1

讓我們看一個簡單的例子,假設S = 「中的」

我們將有:

REV(T) - >增加指針

REV(H) - >增量指針

REV(E) - >增量指針

REV( '\ 0')(這將只返回)

然後我們將回轉(e)中的主體,其將打印E

然後回到REV(H),其將打印ħ

然後最後回到REV(噸),其將打印牛逼

的順序,然後我們將有:EHT(以下簡稱「」反)

2

讓我們考慮一個長度爲3的字符串。reverse(i)是在字符串的第i個索引上調用的函數的縮寫(從技術上講,它是char指針+ i,但該解釋需要更高級的理解)。

這也是有用的注意(羅伯特指出),其*s返回false如果s\0,表示字符串的結束,所以,在這種情況下,它會簡單地返回。

這裏發生了什麼:

reverse(0) 
    calls reverse(1) 
    calls reverse(2) 
     calls reverse(3) 
     end of string - return 
     prints 2 
    prints 1 
    prints 0 
0

也許會更清楚自己寫函數爲:

void reverse(const char *s) 
{ 
    if(*s) 
    { 
    reverse(s+1); 
    std::cout << *s; 
    } 
} 

即每個NOT NULL characther將調用由調用下一個(後打印以反向)

PD:如果您不會修改給定的字符串,請使用「const char *」而不是「char *」。

3

嘗試可視化調用堆棧的構建方式。每次遞歸調用會創建另一個堆棧幀,並將s的副本加1。當退出條件發生時,堆棧開始展開並且爲每個幀調用語句cout。由於LIFO原則,字符串反向打印。

enter image description here