() 的优先级最高,为什么会短路?

问题描述

() 优先级最高,为什么会短路?

int a = 1,b = 0;
(--a)&&(b++);

为什么 (b++) 仍然短路?

解决方法

表达式 (--a) 使用前缀运算符并计算为 0。这是错误的,并且由于您指出的短路,第二个表达式未计算。

,

我不觉得“短路”这个词特别有用。

最好说 &&|| 具有从左到右的求值顺序。 C 标准 (6.5.13) 实际上很好地解释了这一点:

&& 运算符保证从左到右的评估 ...
如果第一个操作数比较等于 0,则第二个操作数 不计算操作数。

就是这样。左操作数 --a 的计算结果为 0。


What is the difference between operator precedence and order of evaluation?

在这种情况下,重要的是求值顺序。运算符优先级仅保证表达式按预期解析 - 哪个操作数“粘”到哪个运算符上。

,

理解下面的表达式

a * b + c * d

如果假设运算符 + 的操作数是从左到右计算的,那么首先将计算表达式 a * b,然后计算表达式 c * d。

与运算符 + 的操作数计算顺序相关的假设无效。但它对运算符 && 有效。

所以表达式的左操作数

(--a)&&(b++);

首先评估。如果它的值不等于 0,则计算第二个操作数。

来自 C 标准(6.5.13 逻辑与运算符)

4 与按位二进制 & 运算符不同,&& 运算符保证 从左到右求值;如果求值第二个操作数,则有 是第一个和第二个评估之间的序列点 操作数。如果第一个操作数比较等于 0,则第二个操作数 未评估。

,

您是对的,您可以使用括号 () 覆盖运算符优先级。

例如表达式

a && b || c

相当于

(a && b) || c,

因为 && 的优先级高于 ||。您可以通过将其更改为

来覆盖此优先级

a && (b || c)

这样现在 || 的优先级高于 &&

但是,操作符顺序不会改变单个操作符的行为。特别是,两个算子仍然会使用短路。因此,即使 || 的优先级高于 &&&& 运算符仍会在其右侧操作数之前评估其左侧操作数。

在我上面的两个示例中,&& 运算符仍会在计算 ab 之前计算 (b || c)。运算符优先级只会影响 && 运算符的右侧操作数是表达式 b 还是 (b || c)

因此,在您的示例中,通过编写 (--a)&&(b++) 而不是 --a&&b++,您只是确保 --++ 运算符优先于 {{1} } 操作员。这不是必须的,因为他 C 语言指定这些运算符已经有优先级。

在 C 语言指定 && 运算符优先于 &&-- 运算符的假设场景中,表达式 ++ 将被解释为 --a&&b++,并且有必要编写 --(a&&b)++ 以防止这种解释。但事实并非如此。