--x
x-1
之间有什么区别?
我有一个计算前n个数之和的方法
我尝试使用100,结果如下:
int sumaRec(int _suma){
if (_suma > 0)
{
return _suma + sumaRec(--_suma);
}
else
return 0;
}
当我添加--_suma
时,结果为4950
,当我添加_suma -1
时结果为5050
任何人都可以解释原因吗? 请。
答案 0 :(得分:6)
这是详细说明评估问题的顺序。
以下是C ++ 11标准关于评估顺序的内容:
如果对标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值进行的值计算未被排序,则行为未定义。 (§1.9[intro.execution] / p15)
现在我们可以将这些规则应用于此表达式:_suma + sumaRec(--_suma)
。
+
运算符的两个操作数的评估未被排序。编译器可以先评估_suma
,然后sumaRec(--_suma)
,或者反过来。--_suma
之前,sumaRec
的值计算和副作用已按顺序排列。sumaRec
召唤本身,所有内容都是不确定的。也就是说,编译器可以在执行_suma
函数中的语句之前或之后评估sumaRec
,但不能在它期间评估{.1}。+
运算符的结果之前,对+
的两个操作数的值计算(但不是副作用)进行了排序。特别是,因为对于使用相同标量对象的值的值计算,对标量对象(_suma
)的副作用(存储递减的值)是未序的(计算值的计算) <{1}}的第一个操作数,行为未定义。
符合标准的编译器可以执行以下任何操作:
+
,_suma
秒,--_suma
第三sumaRec
,--_suma
秒,sumaRec
第三_suma
,然后评估--_suma
秒,_suma
第三sumaRec
的值计算,--_suma
秒的值计算,_suma
的副作用(存储递减的值)第三,--_suma
第四值得强调的是,运算符优先级和评估顺序完全不同。运算符优先级意味着编译器将sumaRec
这样的表达式解释为f() + g() * h()
而不是f() + (g() * h())
,但无法保证(f() + g()) * h()
,f()
,并且g()
将按任何特定顺序进行评估。实际上,如果此表达式在同一代码中出现两次,则编译器甚至不需要一致:评估顺序可以是一个h()
,另一个是f(), g(), h()
编辑:要注意GCC,如预期的那样emits a warning代码:
g(), f(), h()
在启用完整警告的情况下进行编译总是一个好主意。
答案 1 :(得分:3)
基本区别在于,当您执行x-1
时,x的值保持不变。但是当你执行--x
时,x的值会递减。所以,
让,
x=4;
y=x-1;
现在,在这种情况下,x是4,y是3.现在,对于相同的x = 4,
y = --x;
现在x和y都是3。
答案 2 :(得分:1)
前缀减量修改您正在使用的变量,不仅要将其发送到函数,还要在序列计算中。这就是你最终计算错误的原因。
我建议你把减法放在一个临时变量中,然后将该变量传递给你的函数。