下面是递归函数,用于计算自然数之和直至n
。
int calculateSum(int n) {
if (n == 0){
return 0;
}else{
return n + calculateSum(--n); //Replacing --n with n-1 works
}
}
输入:5
如果我使用--n
,则输出为10 ,但是当我将--n
替换为n - 1
时< / strong>,然后返回正确的结果(15)。为什么会有所不同?
答案 0 :(得分:12)
令人惊讶的是,表达式的行为
n + calculateSum(--n);
是未定义,因为--n
不仅在递减1后求值为n
,而且还将n
更改为新值。但是,相对于左侧n
的 other 评估(值计算),该变化(副作用)是未排序的。根据{{3}},行为是不确定的,
相对于相同标量对象的不同副作用或使用相同标量对象C11 Appendix J.2.的值进行的值计算,相对于标量对象的副作用没有顺序。
(6.5)中有更多同类错误。
当您输入错误的值时,您可以认为自己很幸运,因为编译器还可能生成了返回“正确值” ...的代码,其中给出了月球的相位,优化设置或调用函数中的行数...
答案 1 :(得分:4)
--n
还修改了局部变量n
;表达式n-1
仅返回减小后的值,以将其传递给递归调用,但不会修改您的输入参数。
有关输入5
的第一次迭代的详细信息:
return 5 + calculateSum(5-1);
--n
,您还将从n
开始递减,最后得到4 + calculateSum(4)
@ user3386109和@Yunnosch这样写:
使用--n
可以计算总和0...(5-1)
而不是0...5
。
请参阅@Antti答案,它说明这实际上是未定义的行为。
答案 2 :(得分:-1)
以下代码段(一个函数),您可以在主函数中调用它,该函数将递归返回n个自然数之和
int NNumbers(int n)
{
if(n != 0)
return n + NNumbers(n-1);
else
return n;
}
在您的代码中,您要递减n的值,然后您要计算总和(即Pre-Decreament),因为输入为5,因此每次迭代时递减1,然后将其相加自然数。因此您得到的结果是10,而不是15
希望这对您有所帮助:) 谢谢