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

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

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

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

【问题讨论】:

标签: c operators short-circuiting logical-and


【解决方案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,则第二个操作数 未评估。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-17
          • 1970-01-01
          • 2017-02-17
          • 2023-04-01
          • 1970-01-01
          • 2016-04-04
          • 2016-09-28
          • 1970-01-01
          相关资源
          最近更新 更多