为什么这个递归(我不确定,我发现这段代码说它是“递归”的)代码崩溃(我在互联网上发现了这种奇怪的方法,但我真的不知道它是如何工作的)输入值>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;
}发布于 2022-04-01 21:24:01
递归版本每次调用自己时都会使用少量的堆栈空间,因此它受到堆栈大小的限制,如果它多次调用自己,则会崩溃。这是一个典型的堆栈溢出错误。
迭代的第二个版本没有这个问题。
发布于 2022-04-01 21:51:18
你的第一种方法
第一种方法是递归的。这意味着它对每一个k调用一次函数sum(),假设k是2,而sum()被调用两次,以此类推。
每个函数调用都需要在堆栈上为其参数、局部变量和一些管理数据(如堆栈指针)、程序在函数返回时跳到的返回地址以及其他一些内容占用空间。当您经常调用sum()时,让我们说大约4000次,堆栈上没有足够的空间供下一次调用sum()时使用。结果导致堆栈溢出,应用程序崩溃。
在应用程序崩溃之前,您可以提供的最大k值取决于您的系统。这意味着,在具有“大”堆栈的Windows、Linux或MacOS桌面上,您可以使用k=大约4000次调用函数,而在嵌入式系统中,每个线程的堆栈可能更低,应用程序也会更早崩溃。
你的第二种方法
第二种方法不是递归的,因此对其他函数的调用不需要堆栈上的任何额外空间。因此,您的应用程序不会崩溃,因为您没有从第一种方法获得堆栈溢出。
此外,您的第二种方法应该运行得更快,因为您不需要花时间进行许多函数调用。
https://stackoverflow.com/questions/71712855
复制相似问题