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

问题描述 投票:2回答:3

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

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

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

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

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

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

c increment operator-precedence postfix-operator
3个回答
2
投票

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

但是++表示post增量,因此执行的[[after a被评估为分配给b

如果您都想取值2,请执行预递增:

b = ++a;


5
投票
这与优先级无关。这取决于后缀++运算符的工作方式。

后缀++运算符求值为其操作数的

当前值,和具有增加其操作数的副作用。相反,前缀++运算符的计算结果为其操作数的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节中有说明:

后缀的结果++运算符是操作数的值。副作用是,操作数对象的值增加(即值1的类型添加到其中)。

请参阅加法运算符和化合物赋值以获取有关约束,类型和转换以及对指针的操作。结果的数值计算在更新存储的副作用之前进行排序操作数的值。关于不确定顺序的函数调用,后缀的操作++是单个评估。后缀具有原子类型的对象上的++是具有memory_order_seq_cst内存顺序语义的读-修改-写操作。并且前缀++运算符在6.5.3.1p2节中有说明:

前缀的操作数的值++运算符增加。

结果是递增后操作数的新值。

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

3
投票
优先级

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

++运算符(一元和后缀形式)具有

结果

副作用。在表达式b = a++中,a++结果a的当前值-这就是分配给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
实际评估顺序取决于您的编译器,优化设置,甚至周围的代码。 

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

© www.soinside.com 2019 - 2024. All rights reserved.