问题描述
() 优先级最高,为什么会短路?
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)
这样现在 ||
的优先级高于 &&
。
但是,操作符顺序不会改变单个操作符的行为。特别是,两个算子仍然会使用短路。因此,即使 ||
的优先级高于 &&
,&&
运算符仍会在其右侧操作数之前评估其左侧操作数。
在我上面的两个示例中,&&
运算符仍会在计算 a
或 b
之前计算 (b || c)
。运算符优先级只会影响 &&
运算符的右侧操作数是表达式 b
还是 (b || c)
。
因此,在您的示例中,通过编写 (--a)&&(b++)
而不是 --a&&b++
,您只是确保 --
和 ++
运算符优先于 {{1} } 操作员。这不是必须的,因为他 C 语言指定这些运算符已经有优先级。
在 C 语言指定 &&
运算符优先于 &&
和 --
运算符的假设场景中,表达式 ++
将被解释为 --a&&b++
,并且有必要编写 --(a&&b)++
以防止这种解释。但事实并非如此。