我正在使用C运算符优先级表来更好地理解C的运算符优先级。在理解以下代码的结果时遇到问题:
int a, b;
a = 1;
b = a++; // does not seem to follow C operator precedence
使用C运算符的优先级表,我无法解释为什么使用后缀++
运算符,首先评估赋值,然后求增量。
后缀增量运算符(++
)在C中具有最高优先级,而赋值运算符(=
)具有最低优先级。因此,在上面的代码中,必须先执行后缀++
,然后再分配=
。因此,变量a
和b
都应等于2,但不等于2。
为什么C运算符优先级似乎不适用于此代码?
什么时候后缀++
的最高优先级不显示出来?
优先级发生在解析期间。这意味着++
适用于a
,而不适用于b = a
。
但是++
表示post增量,因此执行的[[after a
被评估为分配给b
2
,请执行预递增:b = ++a;
++
运算符的工作方式。后缀++
运算符求值为其操作数的
当前值,和具有增加其操作数的副作用。相反,前缀++
运算符的计算结果为其操作数的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)
。有关信息,请参见加法运算符和化合物分配的讨论。约束,类型,副作用,转换以及对指针的操作。仅确定在解析期间将哪些运算符与哪些操作数分组。 不控制评估顺序。优先级高于++
的=
仅表示将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
的表达式中,a
在b
之前更新。同样,评估顺序可能类似于b <- a + 1
a <- a + 1
实际评估顺序取决于您的编译器,优化设置,甚至周围的代码。唯一强制从左到右计算表达式的运算符是
&&
,||
,?:
和逗号运算符。