int i=2;
i = ++i + ++i + ++i;
哪个更正确?Java的结果是12还是C = 13。如果不是正确性的问题,请详细说明。
int i=2;
i = ++i + ++i + ++i;
Java保证(§15.7.1)表达式将从左到右进行求值,得出12。具体来说,++
比+
有更高的优先级。所以它首先绑定这些运算符,然后从左到右关联加法操作。
i = (((++i) + (++i)) + (++i));
根据§15.7.1,左操作数先被求值,而§15.7.2规定在运算前两个操作数都会被求值。因此它的求值顺序如下:
i = (((++i) + (++i)) + (++i));
i = ((3 + (++i)) + (++i)); // i = 3;
i = ((3 + 4) + (++i)); // i = 4;
i = (7 + (++i)); // i = 4;
i = (7 + 5); // i = 5;
i = 12;
在C语言中,如果没有序列点,就连续两次修改变量是未定义的行为。
i = (i*=2) + (i*=3) + (i*=4);
这样的语句有关,其中顺序很重要。 - Kobi++i - ++i - ++i
,并且从左到右的顺序变得非常重要。 - PaulMcG((3 + 4) + (++i))
д№ӢеҗҺзҡ„жӯҘйӘӨдёҚеә”иҜҘжҳҜ((3 + 4) + 5)
еҗ—пјҹеӣ дёә++
жҜ”+
зҡ„дјҳе…Ҳзә§жӣҙй«ҳгҖӮ - configurator没有更加正确的一说。这实际上是未定义的,被称为序列点错误。 http://en.wikipedia.org/wiki/Sequence_point
Java的结果对我来说是有意义的,因为运算符给出了你所期望的结果,但是没有任何严肃的程序应该包含这样的语句。
编辑:我很高兴这个简短的回答成为了今晚我得分最高的答案(与我发布的其他答案相比,其中一些还包括了代码示例)。这就是生活。
在C语言中,这是未定义行为。没有正确的行为。
++i + ++i
是未定义行为,但它并不违反语言约束,这让我有些惊讶。更重要的是,如果调用者为p和q传入不同的值,则int incboth(int *p, int *q) { return ++*p + ++*q; }
是可以的,如果使用相同的指针值两次调用则不行。显然编译器无法帮助您解决这个问题(尽管C99的restrict
至少表明了意图),这就是为什么序列点规则不能完全表示为语言约束的原因。 - Steve Jessop