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

Posted

技术标签:

【中文标题】() 优先级最高,为啥会短路?【英文标题】:() has the highest priority, why is it short-circuited?() 优先级最高,为什么会短路? 【发布时间】:2021-06-03 02:11:21 【问题描述】:

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

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

为什么 (b++) 还是短路了?

【问题讨论】:

你的情况是假的?我认为这是正确的,因为 b 被评估 (0) 然后递增。 为什么括号会改变短路? 优先级不会直接影响计算顺序。它只影响语法树 Operator precedence tells us how an expression is structured, not how it is evaluated. 【参考方案1】:

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

例如,表达式

a && b || c

等价于

(a && b) || c,

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

a && (b || c)

所以现在|| 优先于&&

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

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

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

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

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

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

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

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

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


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

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

【讨论】:

【参考方案4】:

要理解,请考虑以下表达式

a * b + c * d

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

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

所以表达式的左操作数

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

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

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

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

【讨论】:

以上是关于() 优先级最高,为啥会短路?的主要内容,如果未能解决你的问题,请参考以下文章

线程优先级

线程优先级

为啥下面的表达式返回 true?

RabbitMQ

定义int i=1,在执行while(i++<5)后,i的值为?为啥呢

为啥说stm32 的i2c鸡肋