我正在尝试在c ++中编写一个简单的递归和函数:
long long int recursum(long long int n){
if(n==1)
return 1;
else
return recursum(n-1)+n;
}
这应该可行,但我得到的值大于~250000的段错误。我非常确定这应该有效,因为这是一个非常简单的带有终止语句的递归。
答案 0 :(得分:2)
您必须激活编译器的优化,以尝试“解除”函数,以免爆炸您的调用堆栈。
在我的计算机上测试的示例
#include <iostream>
long long int recursum(long long int n){
if(n==1)
return 1;
else
return recursum(n-1)+n;
}
int main(int argc, char const *argv[])
{
std::cout << recursum(99000) << std::endl;
return 0;
}
不乐观:
$ ./a.exe
Segmentation fault (core dumped)
使用g++ -O3
:
$ ./a.exe
4900549500
我甚至尝试使用500000。
尾部递归优化和类似的事情(我不知道其他人的名字)如果没有特定的优化需求就不会完成。
答案 1 :(得分:0)
您的代码适用于正面n
。对于整数n < 1
,它永远不会终止。
针对您的具体问题,您的筹码已用尽causes a segfault。
答案 2 :(得分:0)
对于那个微不足道的问题或总结,有更好的方法来计算这一点。
尝试N * (N+1) / 2
或迭代(for ...)
答案 3 :(得分:0)
对于初学者,您需要将其限制为无符号整数:
unsigned long long recursum(unsigned long long n)
要防止堆栈填满,请查看您的编译器是否支持Tail Recursion Optimization。这基本上可以防止它必须使用这样的递归函数来泛滥调用堆栈。我还会修改你的函数来处理0(你当前没有这样做):
unsigned long long recursum(unsigned long long n)
{
return n ? n + recursum(n - 1) : n;
}
或支持TRO的版本:
unsigned long long recursum(unsigned long long n, unsigned long long result = 0)
{
return n ? recursum(n - 1, result + n) : result;
}
答案 4 :(得分:0)
看起来您的编译器没有进行尾递归优化,并且您收到stackoverflow错误。尝试使用编译器中的优化标志,或者在不递归的情况下重写函数。
long long int recursum(long long int n)
{
long long int result = 0;
for (int i = 1; i <= n; ++i)
result += i;
return result;
}
答案 5 :(得分:0)
我猜这个堆栈不够大,不能超过250000个递归方法调用。
程序必须记住每次递归调用的返回地址,因此必须将250000个跳转地址保存在堆栈中。这可能超过了堆栈。