提问人:mizzadnan 提问时间:10/4/2023 最后编辑:mizzadnan 更新时间:10/4/2023 访问量:77
如何在 C 中计算包含递增和递减运算符的逻辑表达式?
How are logical expressions that include increment and decrement operators evaluated in C?
问:
int a = 0, b= 1, c = 1;
if (c-- || ++a && b--)
我知道 && 的优先级在这里是最高的。那么会发生什么呢?它是否从 && 开始,然后查看其左侧的表达式 (c-- || ++a) 并首先计算它?
我已经尝试了一段时间的不同表达方式,但我就是无法理解它。提前致谢。
编辑:如果可以的话,我会使用括号,但这是一个单一的问题,所以我真的没有发言权
答:
运算符优先级并不能完全确定评估顺序。它的作用是指示操作数的分组方式。由于优先级高于您指出的优先级,因此您的表达式等效于:&&
||
(c-- || (++a && b--))
鉴于操作者使用短路评估,将在评估之前进行评估。但是,整个子表达式是算子的右侧,该算子也使用短路评估,这意味着左侧,即 将首先接受评估。&&
++a
++b
++a && b--
||
c--
由于计算结果为 1,因此不计算运算符的右侧,即 。所以被递减,保持不变。c--
||
++a && b--
c
a
b
由于运算符优先级,这相当于
if (c-- || (++a && b--))
逻辑运算符从左到右处理短路。所以这个首先执行.这递减到 ,但因为它是递减后的,所以该值是它的原始值。这是事实,因此操作员会立即评估到不评估其右手操作数。c--
c
0
1
||
1
所以条件是真的,但只是被修改了。c
我知道 && 的优先级在这里是最高的。
井。。。不。后缀运算符的优先级最高,次高是前缀 ,然后是 ,然后是 。--
++
&&
||
运算符优先级/关联性仅与确定哪些操作数“粘附”到哪个运算符有关。在这种情况下,运算符优先级使表达式等同于 。(c--) || ((++a) && (b--))
从那时起,我们可以忘记运算符的优先级,而是担心计算的顺序。通常,C 中的运算符不会指定操作数的计算顺序。逻辑 AND 和 OR 在这里是例外,明确说明了定义的计算顺序 (C17 6.5.13):
与按位二进制运算符不同,运算符保证从左到右的计算;如果计算第二个操作数,则在第一个操作数和第二个操作数的计算之间有一个序列点。如果第一个操作数比较等于 0,则不计算第二个操作数。
&
&&
类似的文本也存在。这些特殊的评估规则通常被称为“短路评估”,这是一个相当无益的类比(详情:“短路”算子是什么意思?||
)
所有这些都意味着编译器必须建立一个内部表达式解析器树,其中的子表达式只有在整个表达式得到求值时才会得到求值,而这反过来又取决于 的求值结果。++a && b--
(c--)
因此,编译器必须将表达式计算为:
- 评估,如果结果为 1,则停止评估。然后执行。
c--
1
c--
- 否则,请评估并执行 .如果 ,则结果为 0,则停止计算。然后执行。
++a
0
c--
- 否则,请评估 .如果为“1”,则结果为 1,否则为 0。 然后被处决。
b--
c--
b--
评论
if ((c-- || ++a) && b--)
if (c-- || (++a && b--))
++
--