如何证明优先级为 table 的 C 后缀递增运算符?

How to justify C postfix increment operator with precedence table?

我正在使用 C 运算符优先级 table 以更好地理解 C 的运算符优先级。我在理解以下代码的结果时遇到问题:

int a, b;
a = 1;
b = a++;   // does not seem to follow C operator precedence

使用C运算符的优先级table,我无法解释为什么使用后缀++运算符,首先计算赋值,然后计算增量。

后缀自增运算符(++)在C中的优先级最高,赋值运算符(=)的优先级最低。所以在上面的代码中,必须首先执行后缀 ++,然后执行赋值 =。因此,变量 ab 应该等于 2 但它们不等于。

为什么 C 运算符优先级似乎不适用于此代码?

后缀 ++ 的最高优先级什么时候不显示出来?

这与优先级无关。这是后缀 ++ 运算符如何工作的问题。

后缀 ++ 运算符计算其操作数的 current 值, 具有递增其操作数的副作用操作数。相反,前缀 ++ 运算符的计算结果为其操作数的 incremented 值。

int a, b;
a = 1;
b = a++;   // b is 1, a is 2
b = ++a;   // b is 3, a is 3

后缀 ++ 运算符的这种行为记录在 C standard:

的第 6.5.2.4p2 节中

The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The value computation of the result is sequenced before the side effect of updating the stored value of the operand. With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation. Postfix ++ on an object with atomic type is a read-modify-write operation with memory_order_seq_cst memory order semantics.

并且前缀 ++ 运算符记录在第 6.5.3.1p2 节中:

The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation. The expression ++E is equivalent to (E+=1) . See the discussions of additive operators and compound assignment for information on constraints, types, side effects, and conversions and the effects of operations on pointers.

优先级发生在解析期间。这意味着 ++ 适用于 a,而不适用于 b = a

但是++表示post递增,所以执行after a被评估为分配给 b

如果你想让两者都取值2执行预递增:

b = ++a;

优先级 确定在解析过程中哪些运算符与哪些操作数分组。它 控制求值顺序。 ++ 的优先级高于 = 仅意味着 b = a++ 被解析为 b = (a++) 而不是 (b = a)++

++ 运算符(一元和后缀形式)有一个 结果 和一个 副作用 。在表达式 b = a++ 中,a++resulta 的当前值 - 这就是分配给 b 的值。 a++副作用a加1。

分配给 b 和更新给 a 的顺序是 未指定。最直接的就是

b <- a
a <- a + 1

但也允许以下内容:

tmp <- a
a <- a + 1
b <- tmp

++a的结果是a的当前值加1,副作用是a加1。 不要假设 在像 b = ++a 这样的表达式中 ab 之前更新。同样,评估顺序可能类似于

b <- a + 1
a <- a + 1

实际的评估顺序取决于您的编译器、优化设置,甚至是周围的代码。

唯一强制从左到右计算表达式的运算符是 &&||?: 和逗号运算符。