Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用多个逻辑NOT运算符计算条件时出现混淆_C++_C - Fatal编程技术网

C++ 使用多个逻辑NOT运算符计算条件时出现混淆

C++ 使用多个逻辑NOT运算符计算条件时出现混淆,c++,c,C++,C,当代码包含多个非运算符时,我感到困惑,例如: if (!x != !0) ; 或类似的。我可以这样理解:如果x不等于0, 但在我看来,我完全搞不懂它到底意味着什么 你对此有什么建议吗?即如何理解此类代码、从何处开始阅读等 另一个例子: if(!x == !1) 如果您不确定,可以使用。比如说 x | 0 | x!=0 | !x | !0 | !x != !0 0 | 0 | 0 | 1 | 1 | 0 1 | 0 | 1 | 0 | 1 | 1 如果你对

当代码包含多个非运算符时,我感到困惑,例如:

if (!x != !0)
  ;
或类似的。我可以这样理解:如果x不等于0, 但在我看来,我完全搞不懂它到底意味着什么

你对此有什么建议吗?即如何理解此类代码、从何处开始阅读等

另一个例子:

if(!x == !1)
如果您不确定,可以使用。比如说

x | 0 | x!=0 | !x | !0 | !x != !0
0 | 0 |  0   |  1 |  1 |    0
1 | 0 |  1   |  0 |  1 |    1

如果你对许多&&和| |有问题,请使用

我假设问题是关于C的,因此我将用C给出答案

您需要知道优先规则-即
绑定比
强=。因此,可以使用括号澄清表达式,如
(!x)!=(!0)
。现在,接下来要知道的是什么
将执行-如果操作数为非零,则结果将为
0
,如果操作数为零,则结果将为
1
。因此,
!0
可以被常数折叠为
1

现在我们有了
(!x)!=1
。因为
!x
为1如果如果
x
为零,则整个表达式的结果将为1如果
x为非零,否则为0


因此,我们可以将此表达式简化为更惯用的双重否定:
!!x
。但是,
if
子句本身测试表达式是否为非零,因此整个
if
语句可以更改为
if(x)
(由于表达式只保护null语句,因此可以完全忽略它)

要使事情更简单,请计算
运算符先读L->R

要记住的事情:

!0 = 1 // true
!1 = 0 // false
因此,您的情况可以简化为:

if (!x != true)  // !0
if (!x == false) // !1
现在,任何倒置的非零值都将
为零

int x = 10;
!x // zero
反转时的零为

int x = 0;
!x // one

<> > C >或C++,<代码>真< /COD> <代码> 1 < /COD>和<代码> false >代码> 0 < /代码> < /P> < P>我在PowerBuilder上开发Simalar语法时也遇到了麻烦,然后我意识到我只需要想象它是嵌套的if检查false。 例如如果(x)=false,则x变为,因此当x为false或零时,更清楚地表明为true。 在C中,0是假的,任何不是零的都是真的

同样的道理!1永远是虚假的!0总是正确的,尽管我看不出以这种令人困惑的方式键入它的原因,也许您正在查看的代码来自某种自动生成器/转换器。

首先看一看。您将看到类似
优先于同类
=

其次,什么是
!0
-这听起来似乎有一个从
int
bool
的隐式转换,否则
!0
将毫无意义


在您的示例中,您需要首先计算逻辑运算符(即
!x
!0
),然后检查它们是否不相等
=。也就是说,这种代码是<强>真的坏< /强>,因为它是<强>真的很难读< /强> -避免编写这样的代码,如果可能的话(并且考虑重构它-当被单元测试覆盖时-如果你在“野生”中遇到它)

< p>这个代码是用来欺骗你的。你的大脑很难处理双重否定或三重否定(而且你不是唯一一个)

您需要知道什么是优先级规则,并应用它:

(!x==!1)
等于
(!x==(!1))

如果您在代码审查期间看到这种代码,您应该明确地突出显示它,并要求更新

请注意,在C++中,你也可以使用<代码>不< /COD>而不是<代码>!<代码>。它可以使事情更容易理解:


< > >(x==1)<代码>等于<代码>((x)==(1))< /C> >/P>< P>在C和C++中,0的值被认为是“false”,非零值被认为是“true”。但有时会令人困惑,有时会引起一些小问题,两个不同的值都可以被认为是正确的,即使它们是不同的

例如,假设您有一个函数
is_rich()
,它告诉您一个人是否富有。假设您编写了如下代码:

int harry_is_rich = is_rich("Harry");
int sally_is_rich = is_rich("Sally");
现在变量
harry\u is\u rich
根据harry是穷还是富是零或非零,而
sally\u is\u rich
根据sally是穷还是富是零或非零

现在假设你有兴趣知道哈利和萨利都是富人还是穷人。你的第一个想法可能是

if(harry_is_rich == sally_is_rich)
但是等等。由于任何非零值在C中都被认为是“true”,那么如果由于某种原因,
is_rich()
函数在Harry富有时返回2,在Sally富有时返回3,会怎么样?这本身并不是一个bug-
is_rich()
函数完全符合其规范,即如果某人富有,则返回非零-,但它会导致无法编写的情况

if(harry_is_rich == sally_is_rich)
(当然,您可以编写它,但与任何错误代码一样,它可能无法正常工作。)

那么你能做些什么呢?嗯,一种可能性是写作

if(!harry_is_rich == !sally_is_rich)
你可以这样理解:“如果不是哈利富有的情况与莎莉富有的情况具有相同的真理价值的话”。而且,虽然它显然有点扭曲,但你可以说服自己,它“意味着”相同的东西

而且,虽然有点混乱,但它有工作的优势。因为C和C++中的真值/假值的其他混淆方面,它是有效的。 尽管如我所说,零被认为是假的,任何非零值都被认为是真的,但生成真/假值的内置运算符——如
&&
|
--实际上保证为您提供精确的0或1。(也就是说,内置函数与
is\u rich()
if(!harry_is_rich == !sally_is_rich)
if(harry_is_rich == sally_is_rich)