我聽到一個神話,說「無限循環或無停止條件的遞歸函數將在」堆棧溢出「時停止。這樣對嗎?什麼時候會無限循環,並且沒有停止條件的遞歸函數最終會停止?
例如:
void call()
{
call();
}
或
for(;;){;}
他們會真的當堆棧溢出停下來?
更新:如果它確實停止,我可以檢測多少次遞歸調用之後?
我聽到一個神話,說「無限循環或無停止條件的遞歸函數將在」堆棧溢出「時停止。這樣對嗎?什麼時候會無限循環,並且沒有停止條件的遞歸函數最終會停止?
例如:
void call()
{
call();
}
或
for(;;){;}
他們會真的當堆棧溢出停下來?
更新:如果它確實停止,我可以檢測多少次遞歸調用之後?
這真的取決於語言的選擇。
在某些語言中,根據系統或語言相關的條件,您的無限遞歸函數將因堆棧溢出而暫停。原因在於函數調用和返回的許多實現爲每個函數調用分配新的空間,並且當空間耗盡時,程序將失敗。然而,其他語言(Scheme和各種gcc優化級別)實際上會讓這個程序永遠運行,因爲它們足夠聰明,意識到它們可以重複使用每個調用的空間。
在某些語言中,無限循環將永遠運行。你的程序將繼續運行,永遠不會取得進展。在其他語言中,編譯器可以對無限循環進行優化。作爲一個例子,新的C++ 0x標準說,編譯器可以假定任何循環都會終止或者做一些全局可見的動作,所以如果編譯器看到無限循環,它可能只是優化循環存在,所以循環實際上終止。
換句話說,它確實取決於。這個問題沒有硬性的答案。
希望這會有所幫助!
你的第一個例子是遞歸方法調用 - 每個call
(在大多數語言和環境中)的調用將創建一個新的堆棧幀,最終你會用完堆棧(你會得到一個堆棧溢出的情況) 。
你的第二個例子不涉及遞歸方法調用 - 它只是一個循環。不需要創建堆棧幀,堆棧也不會溢出。
給你的例子一個鏡頭 - 第一個例子會導致堆棧溢出比你想象的更快。第二個會讓你的粉絲真的很快旋轉,但是除非你殺了它,否則什麼都不會發生。
「更新:如果它真的停止,我可以檢測多少次遞歸調用?「
你肯定可以:
call(int n){
print(n)
call (n+1)
}
然後,只需撥打:
call(1)
當堆棧溢出時,看看最後打印的數字。這是方法的調用數你有。
希望這有助於!
NS
Ø k,那麼有沒有一種方法可以檢測它會流入多少堆棧? – xsari3x
是的。您的計算機擁有一個指向堆棧頂部的指針,並知道堆棧的最大地址。當它被要求創建一個新的堆棧幀時,它會檢查堆棧指針的新值是否不超過該最大地址。 –
你可以檢查我的更新,並提前致謝 – xsari3x