【问题标题】:Changing the precedence of the operators in C更改 C 中运算符的优先级
【发布时间】:2014-01-02 15:53:50
【问题描述】:

由于 && 的优先级比 || 的优先级更多(这是合适的形容词吗?),所以我写了这样的内容:

if (a || b && c ){ ....

我猜程序会先找到b && c,我们就叫它d,然后再找到a || d吧?

我希望程序先检查“a”语句,然后检查是否错误;检查 b 和 c。这样的事情可能吗?

【问题讨论】:

  • 操作的优先级和顺序确实是不同的东西。
  • 好吧,我认为优先级是我正在寻找的单词,我的英语不是很好。对此感到抱歉
  • 简而言之,您不能在 C 中更改运算符的优先级 — 在 C++ 中也不能这样做,即使您可以为您定义的类定义运算符。您可以控制评估的顺序(在某种程度上,使用某些运算符,尤其是&&||?:,)。碰巧的是,您所写的将做您想做的;我想把它写成if (a || (b && c)),让其他读者清楚我想要什么。

标签: c operators operator-precedence


【解决方案1】:

C 中的逻辑表达式服从short-circuit evaluation。现在,正如您所指出的,

a || b && c

一样
a || (b && c)

因为优先。

但是a首先被评估,因为评估顺序是从左到右。由于短路评估,只有当a 为假时,程序才会继续评估b && c。所以,你的代码已经做了你想做的事。

【讨论】:

  • +1 注意:(b && c) 也应该进行短路评估。在测试a 并收到false 后,如果b 为假,则不应评估c。我知道大卫知道这一点,但 OP 可能不知道。
【解决方案2】:

我希望程序先检查“a”语句,然后检查是否错误;检查 b 和 c。这样的事情可能吗?

是的。你走对了。

a || b && c 将被解析为a || (b && c),因为&& 的优先级高于|| 运算符。 bc 绑定到 &&
由于逻辑运算符从左到右计算,首先计算a,如果是true,则不会计算b && c,因为|| 运算符对其操作数执行短路计算。

如果a 被评估为false,那么b && c 将被评估,其中b 被评估,然后是true c 被评估,否则c 不会被评估,因为与&& 对其操作数执行短路评估的原因相同。

【讨论】:

    【解决方案3】:

    我猜程序会先找到b && c,我们称它为d,然后找到a || d,对吧?

    没有。

    首先,运算符优先级只影响运算符和操作数的分组;它影响表达式的计算顺序。一般来说,评估顺序是未指定;例如,在像a + b * c 这样的表达式中,abc 中的每一个都可以以任何顺序进行计算。同样,b * c 必须在 a + b * c 之前评估,但这并不意味着 b * c 必须在 a 之前评估。

    ||&& 运算符的特殊之处在于它们强制从左到右进行评估;首先将全面评估左侧(并应用所有副作用)。此外,两个运算符都使用“短路”评估;如果表达式的值可以从左侧操作数确定,则右侧操作数将不会被计算根本

    由于&& 的优先级高于||,表达式将被解析为a || (b && c),这意味着a 的结果将与b && c 的结果进行或运算。但是,由于||&& 强制从左到右求值,a 将首先求值。如果 a 的结果为 0,则将评估 b。如果b 的结果非零,则将评估c。如果 b 为 0,则不会评估 c。如果a 不为零,则不会评估bc

    下表显示了各种可能性; NZ 表示“非零”,NE 表示“未评估”:

    
    a    b    c      b && c      a || b && c
    -    -    -      ------      -----------
    0    NZ   NZ     true  (1)   true  (1)
    0    NZ   0      false (0)   false (0)
    0    0    NE     false (0)   false (0)
    NZ   NE   NE     NE          true  (1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-24
      • 2017-06-02
      • 1970-01-01
      • 2013-02-09
      相关资源
      最近更新 更多