【问题标题】:Is this not tail recursive? (stack overflow error)这不是尾递归吗? (堆栈溢出错误)
【发布时间】:2013-06-16 06:32:55
【问题描述】:

这是我编写的一个小函数,用于检查整数是否为素数:

int prime(int x, int y = 2)
{
    if(y <= x/2)
    {
        if((x % y) == 0)
            return 0;
    }
    else
        return 1;

    return prime(x, ++y);
}

现在,我用 Visual Studio 2012 编译它,如果我给它一个大的值,例如 105943,就会发生堆栈溢出错误并且代码中断。现在,这个函数不是尾递归吗?如果是这样,那么不应该为递归调用维护堆栈,并且不应该发生溢出?

我到底有什么不明白的地方?

【问题讨论】:

  • 是的,它是尾递归,但是你使用的编译器没有将尾递归优化为循环。
  • @user1831704 如果您指定高优化级别,编译器应该这样做(不知道如何在 Visual Studio 中这样做)。 (clang 对-O 很满意,gcc 需要-O2 来循环它)
  • 我不使用那个编译器,但this 建议将尾调用优化到适当高的优化级别。
  • 或者..你可以把它写成一个迭代算法吗?只是一个想法。
  • 备注一下,不必到x/2,只需要验证到x的平方根即可。这样 x = 105943。你将赢得对函数 prime 的 50 000 次调用。

标签: c++ c visual-c++ recursion tail-recursion


【解决方案1】:

它是一个尾递归函数,但不需要任何编译器将尾递归优化为循环。如果您将优化级别设置得足够高,它就会这样做。但仅此而已。

LISP(和派生语言)是我所知道的唯一一种尾递归实际上是实现要求的语言。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-10
    • 2014-08-27
    • 2016-11-11
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    相关资源
    最近更新 更多