1

可能重复:
任何人都可以解释这些未定义的行为(i = i++ + ++i,i = i++ 等......)
未定义的行为和序列点

好的,我们都知道 i++ 在下一行将值递增 1 并且 ++i 在同一行递增
(如果我在那里错了请纠正我)
,因此对于 c 的示例语句如下:

int a=0;  
printf("%d , %d",++a,a);  

预期的输出应该是1 , 1,但它会给出1 , 0 ,所以人们可能会猜到我在这里要问的是为什么第二次链接 i打印0而不是1 当值已经增加时。

因此,如果后增量没有在同一行中增加值,那么后增量和前增量之间有什么区别?
编辑:将变量的名称从 i 更改为 a 以避免语法混乱。

4

5 回答 5

4

您对增量运算符的理解非常错误。 i++递增i,并返回其旧值;++i递增i,并返回新值。当实际递增发生时,只保证在前一个序列点之后,下一个之前;在您的代码中,这意味着在调用printf.

除此之外(主要是因为这个),如果你修改一个对象的值,你不能在没有中间序列点的情况下在其他任何地方访问它,除非需要确定新值。您违反了此规则,因此您的代码具有未定义的行为。

于 2012-01-12T17:20:35.587 回答
1

这是未定义的行为。允许编译器以任何顺序计算参数。你的编译器只是从右到左计算它,所以最右边的参数是 0,第二个是 1。

编辑:正如赛斯所说,编译器只能自由改变计算顺序,而不是做它想做的任何事情,所以当你不关心顺序时,你可以自由调用函数,但你永远不应该假设一个参数是在另一个之前计算。

于 2012-01-12T17:16:19.873 回答
1

我认为您的问题不在于增量如何工作。您观察到的现象是关于将参数传递给函数的顺序。据我所知,这不是由 c++ 标准定义的,所以它是一种未定义的行为。这意味着不同的编译器可能有不同的实现。例如,一个编译器可以从左到右传递参数,然后另一个编译器可以从右到左传递参数。

您可以在这里更好地阅读序列点http ://en.wikipedia.org/wiki/Sequence_point

于 2012-01-12T17:18:08.093 回答
1
printf("%d , %d",++i,i);

是未定义的行为。

您违反了 C 序列点规则:

(C99,6.5p2)“在前一个序列点和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,应只读先前的值以确定要存储的值。”

于 2012-01-12T17:19:36.110 回答
1

有一次我在某本书中读到,当一个陈述是这样的:

printf("%d , %d",++a,a);

执行从右到左开始,但输出为从左到右。因此,您看到输出为 1 0 - 首先计算 'a' = 0 然后 '++a' = 1,但显示为 1 0

这很奇怪,但它就是这样工作的。

希望这可以帮助。

于 2012-01-12T17:37:24.983 回答