需要一个关于递归的新观点

时间:2018-02-14 23:24:11

标签: c++ recursion

我无法绕过这个。
为什么这两个函数会产生截然不同的结果,
当第4行看起来相同时?

版本I

int factorial(int val) // input=5; output=120
{
    if (val != 0)
        return factorial(val - 1) * val;
    return 1;
}

版本II

int factorial(int val) // input=5; output=0
{
    if (val != 0)
        return factorial(--val) * val;
    return 1;
}

3 个答案:

答案 0 :(得分:6)

如果您不阅读它们,它们看起来完全相同 - 一个说val - 1而另一个说--val

  • val - 1:减法。评估val的值,减去一个
  • --val:减少。将val减少一个,并计算为新值

后一个示例有未定义的行为,因为您尝试在同一行上再次阅读val

答案 1 :(得分:4)

版本2通过--val更改val的值,其中版本1仅从val中减去1,但在执行此操作时不更新val的值。

答案 2 :(得分:1)

使用

return factorial(--val) * val;

导致未定义的行为。不要使用它。

为了评估表达式,编译器可以先评估factorial(--val),然后评估val,然后执行乘法。也可以先评估val,然后评估factorial(--val),然后执行乘法。

如果编译器选择第一个策略,那么该语句等同于:

--val;
return factorial(val)*val;

如您所见,这是不正确的。

如果编译器选择第二个策略,那么该语句等同于:

int res = factorial(val-1)*val;
--val
return res;

如果编译器遵循此策略,您就得到了正确答案。

OTOH,声明

return factorial(val-1)*val;

不会遇到这个问题,并且总是返回正确的值。