【问题标题】:What's this =! operator? [duplicate]这是什么=!操作员? [复制]
【发布时间】:2014-01-28 12:46:35
【问题描述】:

我对这段代码感到惊讶:

if (a =! b) { // let it be on false
    ...
}

a 永远不会被赋值。这个运算符是干什么的?

【问题讨论】:

  • "But a is never assigned by a value" - 你想说什么?
  • 几乎是 Yoda 的 != 运算符。 “a 不等于 b”。更好的是“a,b,不等于”。但是a b =!a,b =! 无法编译。
  • 这与while(i --> 10) 中使用的“转到”运算符--> 非常相似。见stackoverflow.com/questions/1642028/…
  • 你用 C++ 标签标记了这个问题。所以,它实际上可以是任何东西,具体取决于 a 的类型,因为运算符重载。在这种情况下,重载的运算符是=。除非您使用的 C 或 C++ 的变体对此有特殊意义

标签: c++ c operators


【解决方案1】:

这是两个运算符,=!,而不是一个。这可能是一种混淆的写作方式

a = !b;
if (a) {
    // whatever
}

a 设置为b 的逻辑逆,并测试结果是否为真(或者,等效地,b 是否为假)。

或者可能是a != b 的输入错误。

【讨论】:

  • 我想知道这是否是某人尝试输入的拼写错误!= 特别是因为它在 if 语句中
  • 可悲的是,有些人可能只是认为这是“他们的风格”。
  • 谁编写了自己的操作符来编写混淆代码,可以-->地狱。等等,不不不不不不!
  • @Cyber​​ 几乎可以肯定不是打错字,因为它后面的评论根据它的实际作用产生了一种模糊的逻辑意义。如果没有代码,我将无法解释该评论,但它似乎肯定是一致的。
  • 对于主要的混淆点,如果 = 运算符被覆盖以返回除 LHS 以外的其他内容,您可能会获得一些真正的乐趣。
【解决方案2】:

很久以前,当恐龙在地球上漫游并且 C 在 PDP-11 上的第 5 版 UNIX 上运行时,=! 是“不等于”运算符。 Standard C 的创建已弃用此用法,因此现在它意味着“分配逻辑逆”,如a = !b。这是一个很好的论据,总是用空格包围二元运算符,只是为了让 人类 阅读代码的人清楚编译器的想法。

我有点惊讶没有其他人提到这一点,但话说回来,我可能是唯一一个接触过这么老的 C 编译器的 SO 用户。

【讨论】:

  • +1:当我看到// 单行注释时,我排除了任何古老的语法。此代码必须为 C++ 或某些较新版本的 C,因为它没有 /* ... */ 注释。尽管如此,还是有一些琐事。
  • s/dinosaurs/compusaurs :)
  • 这实际上是“这个运算符是什么?”的唯一好答案。所有其他人似乎都试图忽略运营商的存在。
  • 那么,恐龙有我们想象的那么酷吗?
  • 在刚多林强大的国王倒台之前的古代,古代抄写员也会颠倒赋值运算符的顺序,写成a =+ b,表示我们现在呈现为a += b。当空格无关紧要但顺序很重要时,二字运算符有一种令人讨厌的方式与单字运算符混合:考虑a =- ba = -b,与a -= b。这里曾经是龙,但在埃雅仁迪尔杀死了黑色的安卡拉贡并在他的堕落下摧毁了坦戈拉德姆之后,龙不再像以前那么强大了。当我们认为邪恶永远被征服时,我在那里,但它从最黑暗的代码中回来再次困扰我们。
【解决方案3】:

a 在该行中分配了 b 的布尔否定。只是格式错误

if( a = !b ) {

... 以及一个条件内的邪恶隐藏赋值。

【讨论】:

  • 条件内的赋值不是邪恶的......尽管在这种情况下,空格的使用令人困惑。
  • 条件中的赋值确实是邪恶的。当您编写代码以生成可以以最少的努力阅读和理解的内容时,这一点很重要。可读性是可维护性的重要组成部分。所以如果你正在写一个条件 - 让它看起来像一个条件。如果你正在做作业——让它看起来像一个作业。永远不要试图把一个伪装成另一个,或者把一个埋在另一个里面。
  • while (--t) { ... } 很常见,但并不完全是赋值运算符。
  • @Vortico 但它不是那么容易阅读,如果有人写 --t+y 可能会让人头疼,例如
【解决方案4】:
a =! b 

只是一种有趣的放置方式

a = !b

即将not b 分配给a

赋值后表达式的值为a

通过下面的代码,您可以看到表达式a = !b 的值是!false(即true),然后您可以通过检查a 的值来查看分配已经发生,即也是true

#include <iostream>

int main() 
{ 
    bool a = false;
    bool b = false;

    if(a)
        printf("a is true!\n");
    else
        printf("a is false!\n");

    if(a = !b)
        printf("expression is true!\n");
    else
        printf("expression is false!\n");

    if(a)
        printf("a is true!\n");
    else
        printf("a is false!\n");

}

结果:

a is false!
expression is true!
a is true!

【讨论】:

  • 如果你所说的“一种有趣的方式”是指邪恶和混乱,当然:)
  • 这正是我的意思!
【解决方案5】:

Operators in C++

根据 C/C++ 运算符列表,没有诸如 =! 之类的运算符。但是有一个运算符!=不等于比较运算符/关系运算符

有两种可能。

  1. 可能是拼写错误,因为我注意到 =! 运算符位于 if 语句中,并且有人试图键入 != 而不是 =!,因为 != 是返回 true 或 false 的比较运算符。
  2. 可能,开发人员试图将布尔否定的b 分配给a,但他/她犯了错字,忘记在等号后加一个空格。无论如何,这就是编译器解释它的方式。 根据Operator precedence in c++
    • 运算符 Logical NOT (!) 优先级3关联性从右到左
    • 运算符直接赋值(=)优先级16关联性从右到左

【讨论】:

  • 感谢您提供运算符优先级的链接,总体而言,这一点非常重要。
  • 请解释为什么运算符优先级和关联性对于解析a =! b... 很重要
  • =!不是单个运算符,它们是两个。因此编译器使用优先级和关联性来执行这两个运算符。哪个必须执行第一个和第二个。愿这对你有帮助
【解决方案6】:

它们是两个不同的运算符:=(赋值)运算符和! 运算符。它基本上可以翻译成将a 赋值给b 的否定值。

if (a = !b)

但是,用户可能想要写的是!= 运算符:

if (a != b)

【讨论】:

    【解决方案7】:

    这不是一个单一的运算符,但是,它是混淆代码的好方法。

    如果改为 a=!b,则空格可能不会让您相信它是单个运算符。

    除非您将整个语句括在一组括号中,否则编译器会在条件表达式中出现赋值警告,这是该警告何时有用的完美示例。

    这两个语句在功能上是相同的,但一个会生成警告,另一个不会:

    if (a =! b)   // Generates a warning with `-Wparentheses` (gcc)
    
    if ((a =! b)) // No such warning
    

    -括号

    在某些上下文中省略括号时发出警告,例如在需要真值的上下文中进行赋值时,或者当人们经常混淆其优先级的运算符嵌套时。

    当然,这假设您是一个负责任的程序员,并且实际阅读了编译器发出的警告。


    以更合理的方式使用空格,语句实际上是:

    if (a = !b) // Assign A the value of (logical) NOT B and then test the truth
    

    上面提到的编译器警告实际上在编写此代码的人不小心转置!= 的情况下很有用。但是,从您原始问题中神秘的内联 cmets 来看,a = !b 可能是作者的意图。

    【讨论】:

      【解决方案8】:

      C++ 没有=! 运算符,这立即意味着这是一个= 运算符,后跟一个! 运算符。因此,您只需在 if 条件中添加 a = !b

      【讨论】:

        【解决方案9】:

        这都是关于代码的清晰性:

        应该写成:if (a = !b)

        if (a = !b) 与将a 分配给!b 相同。因此,从技术上讲,使用了 2 个独立的运算符,= 是一个赋值操作,! 是一个逻辑表达式。

        只需在=! 之间放置一个空格,就可以解决这种混淆。

        【讨论】:

          【解决方案10】:

          这可能有三个原因:

          1. 这可能是!= 运算符的错误输入,意思是不等于。 例子:

            if (a != b) {
                // a is not equal to b
            }
            
          2. 这可能是错误输入的a == !b,意思是a 不等于b,这通常与布尔值一起使用。 例子:

            if (a == !b) {
                // The boolean a is equal to not b (a is not equal to b)
            }
            
          3. 它可能试图将a 分配给b 的逆。 例子:

            bool a = !b; // Sets a to the opposite of b
            

          【讨论】:

          • 2) 不奇怪,完全错误; 3) 为什么不在 if 语句中?是否有人在无人查看时从作业中删除了返回值?
          【解决方案11】:

          我认为这是写作或印刷错误之一。因为如果我们无法编译此代码,因为它包含编译时错误。这是在 if 子句中,返回类型必须是布尔值。那怎么可能。答案只是一个错误或正如迈克所说的混淆的写作方式

          只有当变量 a 和 b 都是布尔值时才有可能,这将被编译为 a 等于 (not)b 即 (a = !b) 。

          【讨论】:

            【解决方案12】:

            这可以认为a被分配给!b

            【讨论】:

              【解决方案13】:

              我正在尝试回答您的问题,并且与 Mike 的 answer 一致,我只是在补充。

              您也可以通过a=!!b了解。
              代码a=!b 返回0aa=!!b 返回1a

              =! 不是单个运算符,而是这两者的混合。 这些类型的问题会误导学生检查他们的编码技能

              【讨论】:

              • 要链接到答案,只需点击帖子末尾的 分享 按钮,复制链接并输入:[answer](http://link)
              猜你喜欢
              • 1970-01-01
              • 2013-01-11
              • 1970-01-01
              • 2012-03-17
              • 2014-03-23
              • 2018-10-24
              • 2013-05-17
              • 1970-01-01
              • 2023-03-08
              相关资源
              最近更新 更多