这是什么 = ! 运算符?

我对这个代码感到惊讶:

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

但是 a从来没有被赋值。这个运算符是关于什么的?

56677 次浏览

它们是两个不同的运算符: =(赋值)运算符和 !运算符。它基本上可以被转换为将 a赋值给 b的负值。

if (a = !b)

但是,用户可能想写的是 !=操作符:

if (a != b)

这是两个操作符,=!,而不是一个。这可能是一种模糊的书写方式

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

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

也可能是 a != b打错了。

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!

在这一行中,a被赋予了 b的布尔负值,这只是一个格式错误

if( a = !b ) {

以及一个隐藏在某种状态下的邪恶任务。

C + + 没有 =!操作符,这立即意味着这是一个 =操作符,后跟一个 !操作符。因此,您只需在 if条件下使用 a = !b即可。

C + + 中的运算符

根据 C/C + + 操作符列表,没有像 =!这样的操作符,但是有一个操作符 !=(不等于比较操作员/关系运算子)

有两种可能。

  1. 我注意到 =!操作符在 if语句中,有人试图键入 !=而不是 =!,因为 !=是返回 真或假的比较操作符。
  2. 可能,开发人员试图将 b的布尔否定分配给 a,他/她犯了一个输入错误,忘记在等号后面加一个空格。无论如何,这是编译器解释它的方式。 根据 < a href = “ http://en.wikipedia.org/wiki/Operators _ in _ C _ and _ C + +”> c + + 中的运算符优先级 :
    • 操作员 逻辑 NOT (!)优先级3联想性从右到左
    • 操作员 直接赋值(=)优先级16联想性从右到左

这可能有三个原因:

  1. 它可能是 !=操作符的输入错误,意思是不等于。 < em > 示例:

    if (a != b) {
    // a is not equal to b
    }
    
  2. It could be a mistyping a == !b, meaning a is equal to not b, which would most commonly be used with booleans. Example:

    if (a == !b) {
    // The boolean a is equal to not b (a is not equal to b)
    }
    
  3. It could be trying to assign a to the inverse of b. Example:

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

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

如果改为写入 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

上面提到的编译器警告实际上在编写这段代码的人意外地将 !=调换位置的情况下很有用。然而,从您最初的问题中隐晦的内联注释来看,a = !b可能是作者的意图。

很久以前,当恐龙漫游地球和 C 运行在第5版 UNIX 上的 PDP-11,=!是’不等于’操作员。标准 C的创建不赞成这种用法,所以现在它的意思是‘赋值逻辑逆’,就像 a = !b一样。对于总是用空格包围二进制运算符来说,这是一个很好的参数,只是为了让读取代码的 人类清楚地知道编译器在想什么。

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

这完全是关于代码的清晰度:

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

if (a = !b)等于说如果 a被分配给 !b。所以在技术上有两个独立的运算符被使用,=是一个赋值操作,而 !是一个逻辑表达式。

只要在 =!之间放一个 空间就可以解决这个混淆。

这可以采取作为 a被分配到 !b

我认为这是书写或印刷错误之一。因为如果我们不能编译这个代码,因为它保存了一个编译时错误。这是在 如果子句中返回类型必须是布尔型的。那怎么可能。答案只是一个错误或者像迈克说的 含糊不清的写作方式

而且只有当变量 a 和 b 都是布尔型时才有可能,它们将被编译为 A 等于(不等于) b即(a = !B).

我正在努力回答你的问题,同意迈克的 回答,我只是加起来。

你也可以通过 a=!!b来理解它。
代码 a=!b0返回到 a,而 a=!!b1返回到 a

=!不是单个操作符,而是这两个操作符的混合。 这些类型的问题被要求误导学生到 检查他们的编程技能