【问题标题】:Bitwise OR and logical OR operators. What's the difference?按位或和逻辑或运算符。有什么不同?
【发布时间】:2013-03-21 14:57:20
【问题描述】:

以下代码中的逻辑运算符和位运算符在功能上有什么区别吗?使用一种或另一种的原因是什么?

typedef unsigned char BOOLEAN;

void orOperatorsComparison(BOOLEAN bBar, BOOLEAN bFoo)
{
  BOOLEAN bLogicalOr = (bFoo || bBar);
  BOOLEAN bBitwiseOr = (bFoo | bBar);

  ...  
}

【问题讨论】:

  • 如果bBar为真,则变量bFoo甚至都不会被访问......
  • 短路是否只发生在逻辑运算符上?
  • 谢谢大家,我没有想到短路,但这正是我正在寻找的答案。
  • 特别是,如果bBar 是一些指针取消引用或一些数组访问,它会产生很大的不同:当bFoo 为真且bBar 无效时,编码bFoo|bBar[20] 可能会崩溃指针(例如为空,或数组太小)。但是编码bFoo||bBar[20] 可以避免崩溃。
  • @ulidtko 这是一个 C 问题,不应出现在 C++ 常见问题解答中。 C++ 有一个真正的bool 类型,C++ 中的逻辑|| 表达式产生一个bool 类型的结果。在 C 中,由于隐式类型提升,它们产生类型 int。我相信 | 运算符在两种语言中都会产生一个 int 。

标签: c


【解决方案1】:

“支持”是什么意思?

如果它是一个逻辑或你的意思,那么当然你应该总是使用||,因为那是布尔、逻辑、“或”运算符。

它的好处是能够短路,但在这么简单的代码中这并不重要。

如果按位或在不是为了操作位时使用它,我会认为它很奇怪和奇怪(并且应该进行更正)。

【讨论】:

  • 在这种情况下的支持意味着是否在代码审查中产生恶臭。 :) 我同意你的看法,我在这里问了这个问题,看看除了奇怪和怪异(确实如此)之外是否还有其他原因。
  • 我建议将此问题(和答案)设为C-faq 的成员。你介意清理一下答案吗?
【解决方案2】:

布尔值 ||将短路:如果第一个操作数是true,则永远不会计算第二个操作数。相比之下,按位 |总是计算两个参数。

【讨论】:

  • 但这并不重要,因为这两个参数都只是简单的普通无符号字符
  • 虽然这是真的,但您不会注意到机器代码级别的任何差异。任何半体面的编译器都会将其评估为相同的机器代码。
【解决方案3】:

其他答案已经谈到了短路(但这在您的特定代码中不是问题)。但这里有一个关键区别。

如果由于某种原因您的输入值不在 [0,1] 中,那么按位 OR 将为您提供一个可能也不在 [0,1] 中的答案。 保证逻辑 OR 为您提供 0 或 1。

因此,您应该更喜欢逻辑 OR。您的意图是(大概)操纵逻辑值,因此使用非逻辑运算符是不合逻辑的。*


* 双关语肯定是有意的。

【讨论】:

    【解决方案4】:

    在那种特殊情况下,不,结果没有区别:

    1 || 0 == 1
    1 | 0  == 1
    

    所有真值表都适用于此。

    如果您在谈论我们如何获得结果,那么可能会有所不同。使用||,您有一个短路机制:

    BOOLEAN bFooBar = (bFoo||bBar) // if bFoo is TRUE, we never look at bBar
                                   // vs
    BOOLEAN bFooBar = (bFoo|bBar)  // where we take into account both values
    

    总而言之,是的,在某些情况下,您可以错误地使用逻辑和位运算符并获得相同的结果,但是为什么您会永远 em> 这样做?如果您知道它是错误的,并且您知道它可能会导致糟糕的、难以发现的错误,请使用该语言为您提供的工具来完成他们应该做的工作。

    【讨论】:

      【解决方案5】:

      按位或运算符从不短路,而逻辑运算符则短路。也就是说,如果 bFoo 为真,则永远不会评估 bBar

      【讨论】:

        【解决方案6】:

        逻辑和按位之间是否有任何功能差异 下列情况下的运算符?

        是的,有(正如其他人指出的懒惰评估)。

        有什么理由支持其中一个吗?

        如果它们在某种程度上是等价的,那么使用逻辑运算符的情况将是保留该类型的语义。另见:Principle of least astonishment

        【讨论】:

          猜你喜欢
          • 2014-07-01
          • 2020-04-07
          • 1970-01-01
          • 1970-01-01
          • 2011-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多