為什么這個遞回(我不確定,我發現這個代碼的網站說它是“遞回的”)代碼崩潰(我在互聯網上發現了這種奇怪的方法,但老實說我不明白它是如何作業的)輸入值>4000(有時>4023,有時>4015,我真的不明白...)...
#include <iostream>
unsigned long long int sum(unsigned long long int k)
{
if (k > 0) {
return k sum(k - 1);
}
else {
return 0;
}
}
int main()
{
unsigned long long int n;
std::cout << "This program prints the sum of the first N natural numbers.\n\
Enter N: _";
std::cin >> n;
std::cout << "The sum is: " << sum(n) << ".\n\
Press any key to exit...";
system("pause>nul");
return 0;
}
而這不是嗎?
#include <iostream>
int main()
{
unsigned int n;
std::cout << "Questo programma stampa la somma dei primi N numeri naturali.\n\
Prego inserire N: _";
std::cin >> n;
unsigned long long int tmp = 0;
for (n; n != 0; --n) {
tmp = n;
//std::cout << tmp << ' ';
}
std::cout << "La somma \212: " << tmp << ".\n\
Premere un tasto per uscire...";
system("pause>nul");
return 0;
}
uj5u.com熱心網友回復:
遞回版本每次呼叫自己都會占用一點堆疊空間,所以受限于堆疊的大小,如果呼叫自己太多次就會崩潰。這是一個典型的堆疊溢位錯誤。
迭代的第二個版本沒有這個問題。
uj5u.com熱心網友回復:
你的第一種方法
第一種方法是遞回的。這意味著它為每個 k 呼叫一次函式 sum()。可以說,k 是 2,然后 sum() 被呼叫兩次,依此類推。
每個函式呼叫都需要堆疊空間用于其引數、區域變數和一些管理資料,如堆疊指標、函式回傳時程式跳轉到的回傳地址以及其他一些東西。當您過于頻繁地呼叫 sum() 時,可以說大約 4000 次堆疊上沒有足夠的空間用于下一次呼叫 sum()。結果你得到一個堆疊溢位并且你的應用程式崩潰。
在您的應用程式崩潰之前,您可以提供的確切最大值取決于您的系統。這意味著,在具有“大”堆疊的 Windows、Linux 或 MacOS 桌面上,您可以使用 k = 大約 4000 次呼叫該函式,而在嵌入式系統上,每個執行緒的堆疊可能較低,并且您的應用程式會更早崩潰。
你的第二種方法
您的第二種方法不是遞回的,因此不需要堆疊上的任何額外空間來呼叫其他函式。因此,您的應用程式不會崩潰,因為您沒有從第一種方法中獲得堆疊溢位。
此外,您的第二種方法應該運行得更快,因為您不需要時間進行許多函式呼叫。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/455051.html
上一篇:從Spark表中決議嵌套JSON列的更好/更有效的方法
下一篇:F#-使用匿名記錄遞回
