演算子の優先順位と結合性は、前に何が起こり、後に何が起こるかを教えてくれません。演算子の優先順位/結合性はそれとは何の関係もありません。C言語では、「前」や「後」などの時間的関係は、いわゆるシーケンスポイントによって定義され、シーケンスポイントによってのみ定義されます(これは完全に別の話です)。
演算子の優先順位/結合性は、どのオペランドがどの演算子に属しているかを示すだけです。たとえば、式は正式にはととしてa = b++
解釈できます。演算子の優先順位/結合性は、この場合、後者の解釈が正しく、前者が正しくないことを示しています(つまり、の結果に適用され、結果には適用されません)。(a = b)++
a = (b++)
++
b
a = b
b
これもまた、最初にインクリメントする必要があるという意味ではありません。演算子の優先順位/結合性は、もう一度、「最初に」何が起こり、「次に」何が起こるかとは関係がありません。これは、式の結果b++
がに割り当てられていることを示しているだけですa
。定義上、b++
(接尾辞の増分)の結果はの元の値ですb
。これが、の元の値である1a
を取得する理由です。変数がインクリメントされるタイミングは、割り当てられた元の値である限り、まったく関係ありません。コンパイラーは、この式を任意の順序で評価し、いつでも増分することができます。b
b
a
b
b
a
どういうわけか元の値を取得しますb
(そして、その「どういうわけか」が内部でどのように機能するかは誰も気にしません)。
たとえば、コンパイラa = b++
は次の基本操作のシーケンスとして評価できます。
(1) a := b
(2) b := b + 1
または、次のように評価できます
(1) b := b + 1
(2) a = b - 1
b
最初のケースでは実際には最後にインクリメントされ、2番目のケースでは最初にインクリメントされることに注意してくださいb
。ただし、どちらの場合もa
、同じ正しい値、つまり元の値をb
取得します。これは、取得する必要がある値です。
ただし、上記の2つの例は、説明のためだけのものです。実際には、のような式は内部にシーケンスポイントがa = ++b
ありa = b++
ません。つまり、あなたの観点からは、これらの式のすべてが同時に発生します。「前」、「後」、「最初」、「次」、「最後」はありません。このような表現は、一連の小さなステップに意味のある形で分解できないという意味で「アトミック」です。