尾递归:返回陈述位置

时间:2017-03-01 20:35:13

标签: c recursion return tail-recursion

虽然我的程序按照我想要的方式工作,但我很好奇为什么当我做一个小的改变以摆脱一条线时我得到不同的结果?

SELECT id,display FROM (
    SELECT id, display,1 as ordered
      FROM table
     WHERE id in (...) --these need to be first
    UNION
    SELECT id, display,2 
      FROM table
     WHERE id not in (...) --these need to be at the end
)
ORDER BY ordered,id

在功能中,我移动了“回答”;到“answer = 0”的地方,它产生的结果与我预期的不同。有人知道为什么吗? 输入1,4,5和7产生了一个看似随机的数字。 1-10中的任何其他数字产生了正确的答案。 谢谢你的帮助! 干杯, 将

2 个答案:

答案 0 :(得分:3)

因为该函数没有返回,而且这是未定义的行为。删除一行并不一定能改进代码,不要因为代码少而实现,实际上我会像这样编写

int
sum(int input)
{
    int answer;
    if (input > 0) {
        answer = input + (sum(input - 1));
    } else {
        answer = 0;
    }
    return answer;
}

更多“代码”,但也更具可读性。我说“代码”因为它们的编译方式完全相同,但这个版本更易于阅读。

答案 1 :(得分:1)

虽然我同意 Iharob 认为可读性是首要考虑因素,但仍有一些问题需要您尝试将此函数转换为尾递归。

现在,如果您只是这样做:

int sum(int i)
{
    return i > 0 ? i + sum(i-1) : 0;
}

然后该函数是递归的单行,没有未定义的行为,但它不是尾递归。它不是尾递归的,因为递归函数调用不是函数中的最后一个操作,该角色转到添加。您不只是返回递归调用的结果。

幸运的是,这个尾递归非常容易:

int sum(int i, int n)
{
    return i > 0 ? sum(i - 1, i + n) : n;
}

通过引入一个包含总和的新变量,您只需返回递归调用的结果。

如果你必须坚持单个参数原型,你总是可以使sum成为真正的尾递归函数的包装器:

int sum_impl(int i, int n)
{
    return i > 0 ? sum_impl(i - 1, i + n) : n;
}

int sum(int i)
{
    return sum_impl(i, 0);
}