答案 0 :(得分:3)
为了扩展Sulthan的答案,你的表达式有几个问题,至少是简单的赋值(案例2)。
一个。这样做没有任何意义。即使a++
具有可以分配的值(是非空表达式),它也会自动将结果分配给a
本身。所以你所期望的最好等同于
a++;
分配根本无法改善作业。但这不是错误信息。
B中。 Sulthans更换声明是一个更好的案例。更糟糕的是:++
运算符的值为a
(在表达式的开头),以及在将来某个时刻增加a
的效果:增量可以延迟到下一个序列点。
更新操作数存储值的副作用应发生在前一个和下一个序列点之间。
(ISO / IEC 9899:TC3,6.5.2.4,2)
但是赋值运算符=
不是一个序列点(附件C)。
以下是5.1.2.3中描述的序列点:
[列表中不包含赋值运算符和
)
]
因此,表达可以用Sulthan所说的代替:
int tmp = a; // get the value of a
a = a + 1 //post-increment a
a = tmp // do the assignment
结果,a
仍然包含旧值。
或者表达式可以替换为此代码......:
int tmp = a; // get the value of a
a = tmp // assignemnt
a = a + 1 // increment
...使用不同的结果(a
递增)。这是错误消息所说的:没有定义的序列(必须应用操作的顺序。)
您可以使用逗号运算符,
插入序列点(它的主要用途是什么),...
a++, a=a; // first increment, then assign
...但这显示了你想要做的事情的全部意义泄露。
与你的第一个例子相同。虽然?
是一个序列点......:
以下是5.1.2.3中描述的序列点:
...以下运算符的第一个操作数的结尾: [...] 有条件? (6.5.15); [...]
...增量(a++
)和赋值(a=
)都在?
运算符被评估之后,因此再次排序(“以随机顺序”)。
使评论“小心”更具体:不要在表达式中使用增量对象两次。 (除非有明确的序列点)。
int a = 1;
… = a++ * a;
...评估什么? 2? 1?未定义,因为增量可以在第二次阅读a
后发生。