【问题标题】:Uses of & and && operator& 和 && 运算符的使用
【发布时间】:2011-07-09 17:56:54
【问题描述】:

同样的问题也适用于 |和||。

& 和 && 运算符的用途是什么?我能想到的唯一用途是

使用 &
的 int 基本类型(但不是浮点数/小数)的位与 返回布尔值的布尔值/函数的逻辑短路。通常使用 && 运算符。

我想不出我用过它的任何其他案例。
有人知道其他用途吗?

-edit- 澄清一下,我问的是任何语言。我看到 DateTime 使用“-”返回时间跨度,字符串使用“+”创建新字符串等。我不记得使用 && 和 & 的任何自定义数据类型。所以我在问他们(合理地)可以用来做什么?我不知道一个例子。

【问题讨论】:

  • 您说的是特定语言吗?在 JavaScript 中,使用foo = arg || 'default' 设置默认值非常常见。
  • 我不明白这个问题。如果您不需要这些工具,请不要使用它们。这个问题和the other one you asked有什么不同?
  • 您能说明一下您对哪种语言感兴趣吗?在 C++/C# 中,“单”版本(&、|)是按位运算符,“双”(&&、||)是条件运算符。我敢肯定它在其他语言中有所不同。
  • @Tim Croydon:在 C# 中,&| 都是条件运算符和二元运算符。
  • @Guffa:实际上,您刚刚说出了我问这个的原因。我认为 C# 使用这很荒谬 |对于条件和二进制。这就是我问这个问题的原因。查找这些运算符的用途

标签: language-agnostic operators


【解决方案1】:

在大多数基于 C 的语言中,这些运算符的含义是:

  • && - 布尔与。用于布尔表达式,例如 if 语句。
  • || - 布尔或。用于布尔表达式,例如 if 语句。
  • & - 按位与。用于AND 两个操作数的位。
  • | - 按位或。用于OR 两个操作数的位。

但是,保证会如此。由于每种语言都定义了自己的运算符,因此这些字符串可以定义为不同语言中的任何内容。

根据您的编辑,您似乎在使用 C#。以上描述适用于 C#,|& 也是条件运算符(取决于上下文)。

至于您所说的 DateTime+ 运算符 - 这与您提到的其他运算符及其含义无关。

【讨论】:

  • 不,该描述不适用于 C#。 &| 不仅是二元运算符,它们也是条件运算符。
【解决方案2】:

如果您询问所有语言,那么我认为谈论“& 运算符”是不合理的。标记& 可以在不同的语言、运算符等中具有各种含义。

例如,仅在 C 中就有两个不同的 & 运算符(一元地址和二进制位与)。 C 和相关语言中的一元 & 是我能立即想到的唯一示例,这是我遇到的符合您标准的用法。

但是,C++ 增加了运算符重载,因此它们可以为用户定义的类表示任何你喜欢的意思,此外,& 字符在类型声明中也有意义。在 C++0x 中,&& 标记在类型声明中也有意义。

类似于 APL 或 J 的语言可以“合理地”使用 & 运算符来表示几乎任何东西,因为不期望这些语言中的代码与类 C 语言有任何相似之处。不确定这两个是否确实使用&&&

对于 C++ 中的二进制 & 运算符重载来说,“合理”的含义是一个品味问题——通常它在某种程度上类似于按位 &,因为你的类所代表的值在某种程度上可以被认为是一个比特序列。不过,只要它在域中有意义,就不必如此。通常,仅仅因为 & 恰好未使用而使用 & 重载是相当“不合理的”。但是,如果您的课程代表数学中相当深奥的东西,并且您需要在+* 之后的第三个二元运算符,我想您会开始四处寻找。如果你想要的是比+ 更低优先级的东西,二进制& 是一个候选者。我暂时想不出抽象代数中的任何结构都需要这样的东西,但这并不意味着没有。

在 C++ 中重载 operator&& 是适度反社会的,因为运算符短路的未重载版本和重载版本不会。 C++ 程序员习惯于编写像if (p && *p != 0) 这样的表达式,因此通过重载operator&&,实际上是在弄乱控制结构。

在 C++ 中重载一元 operator& 是非常反社会的。它阻止人们将指针指向您的对象。 IIRC 有一些尴尬的情况,标准模板的常见实现需要它们的模板参数,一元 operator& 导致指针(或至少是一个非常类似于指针的东西)。这没有记录在参数的要求中,但是当库编写者来实现模板时,这几乎或完全不可避免。所以重载会限制不能从标准中推导出来的类的使用,最好有一个很好的理由。

[编辑:当我写这篇文章时我不知道,但现在知道了,模板编写者可以解决在标准没有指定 @ 的情况下使用带有模板参数的一元 operator& 的需要987654343@ 适用于该类型(即所有类型)。你可以做boost::addressof做的事情,就是:

reinterpret_cast<Foo*>(&reinterpret_cast<char&>(foo))

该标准不需要太多reinterpet_cast,但由于我们谈论的是标准模板,他们确切地知道它在实现中做了什么,无论如何将对象重新解释为字符是合法的。我认为这可以保证工作 - 但如果不是,实现可以确保它在必要时可以工作,以编写完全符合标准的模板。

但是,如果您的实现没有达到这些长度以避免调用重载的operator&amp;,那么原始问题仍然存在。]

【讨论】:

    【解决方案3】:

    由于您之前关于这些运算符的问题是关于 C#,我认为这个也是。

    通常您希望使用条件运算符的短路版本来避免不必要的操作。如果第一个操作数的值足以确定结果,则不需要计算第二个操作数。

    当一个条件依赖于 previos 条件为真时,只有短路运算符起作用,例如进行空值检查和属性比较:

    if (myObj != null && myObj.State == "active")
    

    在这种情况下使用&amp; 运算符不会阻止对第二个操作数进行求值,并且会导致空引用异常。

    当您希望始终评估两个操作数时,非短路运算符很有用,例如当它们有副作用时:

    if (DoSomeWork() & DoOtherWork())
    

    如果第一个方法返回 false,使用 &amp;&amp; 运算符会阻止调用第二个方法。

    &amp;| 也是二元运算符,但与 ||&amp;&amp; 运算符不同,将它们用作二元运算符时不会有歧义。

    【讨论】:

      【解决方案4】:

      非常笼统的问题,我假设您使用的是 Java、C# 或其他类似语法。在 VB 中,它相当于字符串上的 +,但我认为这是另一个故事。

      据我所知,如果您使用 C# 语言,您的说法是正确的。

      【讨论】:

        【解决方案5】:

        如果是 Javascript,那么请看这个答案:Using &&'s short-circuiting as an if statement?

        那里也有关于 C# 用途的简短讨论。

        Java 还有一些运算符,例如 |= : What does "|=" mean in Java?

        【讨论】:

          【解决方案6】:

          C 使用 & 作为任何数据类型的一元运算符来获取数据的地址

          例如:

          int i = 5;
          cout<<&i;//print the address of i
          

          有些语言允许你重写这些操作符,让它们做任何你想做的事情!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-14
            • 2011-12-29
            • 1970-01-01
            • 1970-01-01
            • 2021-07-14
            • 2012-11-26
            相关资源
            最近更新 更多