考虑经典的序列点示例:
i = i++;
C 和 C++ 标准规定上述表达式的行为是未定义的,因为 = 运算符与序列点无关。
让我困惑的是 ++
的优先级高于 =
因此,上面的表达式,基于优先级,必须计算 i++
先做作业。因此,如果我们从 i = 0
开始,我们应该总是以 i = 0
结束(或者 i = 1
,如果表达式是i =++i
) 而不是未定义的行为。我错过了什么?
最佳答案
所有运算符都会产生一个结果。此外,还有一些运算符,如赋值运算符=
和复合赋值运算符(+=
、++
、>>=
等)产生副作用。结果和副作用之间的区别是这个问题的核心。
运算符优先级控制运算符用于生成结果的顺序。例如,优先规则要求 *
在 +
之前,+
在 &
之前,依此类推。
但是,运算符优先级并没有说明应用副作用。这就是序列点(之前排序、之后排序等)发挥作用的地方。他们说,为了明确定义表达式,将副作用应用到内存中的同一位置必须用序列点分隔。
i = i++
打破了这条规则,因为 ++
和 =
都将它们的副作用应用于同一个变量 我
。首先, ++
去,因为它有更高的优先级。它通过在增量之前获取 i
的原始值来计算其值。然后 =
去,因为它的优先级较低。它的结果也是i
的原始值。
这里缺少的关键是分隔两个运算符的副作用的序列点。这就是行为未定义的原因。
关于c++ - 序列点和运算符优先级有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44770170/