如何用优先级表证明C后缀增量运算符的合理性?

时间:2019-02-06 20:24:34

标签: c increment operator-precedence postfix-operator

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

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

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

后缀增量运算符(++)在C中具有最高优先级,而赋值运算符(=)具有最低优先级。因此,在上面的代码中,必须先执行后缀++,然后再分配=。因此,变量ab都应等于2,但不等于2。

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

postfix ++的最高优先级何时显示?

3 个答案:

答案 0 :(得分:5)

这与优先级无关。这与后缀++运算符的工作方式有关。

后缀++运算符求值为其操作数的 current 值,并且 具有增加其操作数的副作用。相比之下,前缀++运算符的计算结果为其操作数的递增的值。

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部分记录了后缀++运算符的这种行为:

  

后缀的结果   ++运算符是操作数的值。副作用是,操作数对象的值会增加(即值1   适当的类型)。参见有关的讨论   加法运算符和化合物赋值以获取有关   约束,类型和转换以及   对指针的操作。结果的数值计算   在更新存储的副作用之前进行排序   操作数的值。关于   不确定顺序的函数调用,后缀的操作   ++是一个评估。后缀   具有原子类型的对象上的++是具有memory_order_seq_cst内存顺序语义的读-修改-写操作。

第6.5.3.1p2节记录了前缀++运算符:

  

前缀的操作数的值   ++运算符递增。 结果是递增后操作数的新值。表达式   ++E等效于(E+=1)。有关信息,请参见加法运算符和化合物分配的讨论。   约束,类型,副作用,转换以及   指针操作。

答案 1 :(得分:3)

优先级确定在解析期间将哪些运算符与哪些操作数分组。它控制评估顺序。 ++的优先级比=高仅意味着将b = a++解析为b = (a++)而不是(b = a)++

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

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

b <- a
a <- a + 1

,但也允许以下内容:

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

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

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

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

唯一迫使表达式从左到右求值的运算符是&&||?:和逗号运算符。

答案 2 :(得分:2)

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

但是++表示 post 的增量,因此在评估后将 a分配给b

如果您想同时使用值2,请执行预递增操作:

b = ++a;