#include<stdio.h> main() { int i=12; int n; n=(i++)+(i--)+(i--); printf("n=%d\n",n); }
日光倾城4
浏览 2391回答 1
1回答
onemoo
这个 (i++)+(i--)+(i--) 大复合表达式是几个自增减表达式的值的和。i ++ 表达式的值是 i 自增前的值,i -- 表达式的值也是 i 自减前的值,这没错。 但不要忘了这样的自增自减表达式还有副作用——那就是会使 i 自增或自减。在你这个表达式的情况下,C 语言并没有具体规定 i 是何时自增减的[注1],能够确定的只是 i 会在这个语句结束前完成自增减。还有一点,C 语言规定了各个运算符的优先级和结合性,你能够据此判断复合表达式中子表达式的运算顺序。那么对于你的这个例子,你能确定 (i++)+(i--) 肯定会在 +(i--) 前先算。 但是 C 语言并没有规定运算符运算时其操作数的求值顺序[注2]。也就是说其中这些 i ++、i -- 具体是何时求值的也是无法确定的。结合上述两点,根本不能确定在运算时这些 i 都是什么值,事实上这个大表达式得出 36、37、38 什么的都有可能。所以如果你问“为啥结果输出是37?”,我只能说“不知道”。谁知道你的编译器是在哪里把 i 自增的,又在哪里把 i 自减了...... 这个表达式在不同的平台上,用不同的编译器可能就会得出不同的结果。可以说你的这个表达式写错了。虽然这么写符合语法,但这竟然能得出不同的值,难道不应该算是写错了吗!你不应该像这样将自增减表达式连续用在一个对象上。事实上对于写复合表达式一般建议:如果其中有表达式改变了一个操作数的值,那就不要在这个复合表达式中再次使用这个操作数。除非你能确定“改变值”和“使用值”的先后顺序。以上是解答。注1:前面说 C 语言并没有具体规定何时自增减,其实 C 语言对此还是有一些规定的,这涉及到“序列点”的概念。具体请参考我在老问答区的一个回答:http://www.imooc.com/qadetail/87888在表达式中有很多地方会成为“序列点”,我不具体展开说了,具体你这句代码,序列点是语句结束时。注2:在新的 C11 标准中,增加了几条对操作数求值顺序的规定,不过不影响你这个代码的结果。