我正在使用C运算符优先级表来更好地理解C的运算符优先级。在理解以下代码的结果时遇到问题。
int a, b;
a = 1;
b = a++; // does not seem to follow C operator precedence
使用C运算符的优先级表,我无法解释为什么使用后缀++
运算符,首先评估赋值,然后求增量。
后缀增量运算符(++)在C中具有最高优先级,而赋值运算符(=)具有最低优先级。因此,在上面的代码中,必须先执行后缀++
,然后再分配=
。因此,变量a
和b
都应等于2,但不等于2。
为什么C运算符优先级似乎不适用于此代码?
postfix ++的最高优先级何时显示?
答案 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
的表达式中,a
在b
之前被更新。同样,评估顺序可能类似于
b <- a + 1
a <- a + 1
实际评估顺序取决于您的编译器,优化设置,甚至周围的代码。
唯一迫使表达式从左到右求值的运算符是&&
,||
,?:
和逗号运算符。
答案 2 :(得分:2)
优先级发生在解析期间。这意味着++
适用于a
,而不适用于b = a
。
但是++
表示 post 的增量,因此在评估后将 a
分配给b
如果您想同时使用值2
,请执行预递增操作:
b = ++a;