() 优先级最高,为啥会短路?
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,则第二个操作数 未评估。
【讨论】:
以上是关于() 优先级最高,为啥会短路?的主要内容,如果未能解决你的问题,请参考以下文章