我无法绕过这个。
为什么这两个函数会产生截然不同的结果,
当第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;
}
答案 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;
不会遇到这个问题,并且总是返回正确的值。