2015-11-04 41 views
1

在課堂上,我正在帶我的老師讓學生不願意遞歸地調用函數。例如,如果我要打電話的主要功能在下面的代碼:遞歸調用函數爲什麼不好?

if (x > 5) { 
    printf("Your number's too high. Enter a number below 5."); 
    main(); 
} 

我,而不是鼓勵使用:

int x; 
while (x > 5) { 
    printf("\nYour number's too high. Enter a number below 5."); 
    scanf("%d", &x); 
} 

雖然我明白,當函數是一個更簡單的方法關於這個特定的問題,我們被告知要完全避免遞歸,尤其是使用main()。不過,我認爲這是一個相當重要的編程概念。爲什麼要避免這種事情,尤其是在調用main()時?

+4

'主()'一般有它的一些設置代碼和初始化,所以它通常是一個壞主意,在這種情況下遞歸。只有在真正有意義時才使用遞歸 - 某種分而治之的算法 - 而不是循環的替代。 – javanut13

+0

有時堆棧溢出問題......調用一個函數遞歸地爲內存「有時」增加了很多負擔。它通常不會泄氣。 – beebee

+2

遞歸調用函數並不壞。它*不好從一個函數調用「main()」!如果一個簡單的循環會更好地工作,那麼使用遞歸(這涉及一些開銷)也是不好的。這裏有一個有用的線程:http://cboard.cprogramming.com/c-programming/8216-when-use-recursion.html – paulsm4

回答

4

偉大的問題。

有些類型的問題更容易用遞歸來解決,但是一般來說,只要有可能,迭代通常會更高效。簡而言之,原因是每次我們進入一個新的函數時,我們必須保存我們離開的位置以及存在的所有變量,以便當內部函數終止時,我們可以在父母身上恢復。

最後你必須記住每一個父母功能的數據,這將是很多,所以你會耗盡你的記憶。另外,保存數據和創建新上下文以執行新功能的過程需要花費少量時間,這些時間會在您執行數十萬次呼叫時累積起來。

您可以通過閱讀有關計算機體系結構和彙編語言的知識,瞭解更多關於編譯器通過做所有我們認爲理所當然的事情(函數,循環)的很酷東西。

例如,檢查了加州大學伯克利分校的類材料的主題:http://www-inst.eecs.berkeley.edu/~cs61c/fa15/