[英]Loop or Recursive method? Which one is better to use?
我想要求用戶輸入一個小於 10 的值。我正在使用以下代碼。 哪個更好用? 循環或遞歸方法。 有人說我使用遞歸函數方法可能會導致內存泄漏。 這是真的嗎?
class Program
{
static void Main(string[] args)
{
int x;
do
{
Console.WriteLine("Please Enther a value less than 10.");
x = int.Parse(Console.ReadLine());
} while (x > 10);
//Uncomment the bellow method and comment previous to test the Recursive method
//Value();
}
static string Value()
{
Console.WriteLine("Please Enther a value less than 10.");
return int.Parse(Console.ReadLine()) > 9 ? Value() : "";
}
}
在此示例中,遞歸成為問題可能需要很長時間。
如果遞歸方法長時間運行而未完成,則可能會導致堆棧溢出異常。 這是因為每個方法調用都會導致數據存儲在堆棧中(空間非常有限) - 更多信息在這里:
在您的情況下,除非他們輸入大於或等於 10 次負載的數字,或者您的內存很少,否則應該沒問題。
通常使用循環比使用遞歸更好,因為它們更容易理解。 遞歸是在某些情況下實現良好性能的有用工具,但通常應該首選循環。
當您有基本情況和常規情況時,使用遞歸函數。 基本情況至關重要,因為它標志着遞歸的結束。 例如,您可以創建函數factorial(n)
來計算數字n的階乘。 基本情況發生在n達到 1 並且您只返回 1 時,而在常規情況下,您只需將n乘以factorial(
n - 1 )
。
一般來說(有一些優化案例可以節省內存),遞歸函數為每次調用創建一個新的堆棧幀。 因此,對於factorial(3)
,至少創建了三個堆棧幀, factorial(3)
本身, factorial(2)
一個,最后一個完成遞歸的,即factorial(1)
。
至少,在這種情況下,您知道何時完成,以及需要多少內存,因此編譯器可以提前使用。
上面的所有討論都意味着如果您認為可以使用遞歸來驗證用戶輸入,那么您就誤解了遞歸。 只能有一個電話具有正確答案,這將是基本案例,甚至是數百或數千或常規案例實例。 這有可能會溢出程序的堆棧,而編譯器或您無法阻止這種情況發生。
另一種看待這一點的方式是遞歸被用作一種抽象方式:您指定需要發生的事情,即使是在數學問題附近,而不是它應該如何發生。 在您的示例中,不需要這種抽象級別。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.