多条件IF语句的奇怪行为

时间:2017-02-07 10:56:47

标签: c++ boolean-logic

我注意到,在合并!=&&运算符时,我偶然发现了if函数的奇怪行为。例如,我有两个std::string个对象,我想检查它们是否不是"ffff""0000",然后继续进行一些计算。

代码如下所示:

std::string sentData("ffff")
std::string sentAddr("060C")
if (sentData == "ffff") 
    cout << "A 1. Same" << endl;
else 
    cout << "A 1. Different" << endl;
if (sentAddr == "0000") 
    cout << "A 2. Same" << endl;
else 
    cout << "A 2. Different" << endl;
if ((sentData == "ffff") && (sentAddr == "0000")) 
    cout << "A &&. Same" << endl;
else 
    cout << "A &&. Different" << endl;

if (sentData != "ffff") 
    cout << "B 1. Different" << endl;
else 
    cout << "B 1. Same" << endl;
if (sentAddr != "0000") 
    cout << "B 2. Different" << endl;
else 
    cout << "B 2. Same" << endl;
if ((sentData != "ffff") && (sentAddr != "0000")) 
    cout << "B &&. Different" << endl;
else 
    cout << "B &&. Same" << endl;

理论上,我认为它应该产生相同的结果......但它并没有。最后一个if函数将&&视为||(我不知道为什么),因此即使只有一个答案是正确的,我也会进入最后一个if语句。下面有一些答案。

按原样运作:

sentData: ffff  sentAddr: 0000
A 1. Same
A 2. Same
A &&. Same
B 1. Same
B 2. Same
B &&. Same

sentData: ffdf  sentAddr: 060e
A 1. Different
A 2. Different
A &&. Different
B 1. Different
B 2. Different
B &&. Different

工作错误:

sentData: ffff  sentAddr: 060c
A 1. Same
A 2. Different
A &&. Different
B 1. Same
B 2. Different
B &&. Same

sentData: fb8c  sentAddr: 0000
A 1. Different
A 2. Same
A &&. Different
B 1. Different
B 2. Same
B &&. Same

因此,如果我在sentData: fb8c sentAddr: 0000中使用if ((sentData != "ffff") && (sentAddr != "0000")),我会获得if (TRUE && FALSE),但显然它仍会进入if语句。

问:有谁知道为什么?

我问这个是因为我想避免写这样丑陋的代码:

if (!((sentData == "ffff") && (sentAddr == "0000"))) {
    // do stuff
}

if ((sentData == "ffff") && (sentAddr == "0000")) {
    // nothing to do
} else {
    // do stuff
}

2 个答案:

答案 0 :(得分:9)

您认为{{dta}}{{user.name}}相反。

这是因为在布尔运算上分配或取消分配否定需要将布尔运算转换为双重运算,并且否定单个内部项,反之亦然。

这被称为De Morgan's Law,是布尔代数中的基本定律。

因此双重:

!a && !b

实际上是:

!(a && b)

和双重:

(a && b)

实际上是:

(!a || !b)

以下是工作代码:

(!a && !b)

See it live on Coliru.

答案 1 :(得分:1)

由于你似乎仍然有点困惑,我会尝试采用与@VermillionAzure采用的方法不同的方法,以及他的精彩答案。

考虑以下源代码,它具有与您完全相同的测试条件,减去不相关的源代码,但输出描述不同:

if ((sentData == "ffff") && (sentAddr == "0000")) 
    cout << "both are equal" << endl;
else 
    cout << "at least one is different" << endl;

if ((sentData != "ffff") && (sentAddr != "0000")) 
    cout << "both are different" << endl;
else 
    cout << "at least one is equal" << endl;

这是输出:

sentData: ffff  sentAddr: 0000
both are equal
at least one is equal

sentData: ffdf  sentAddr: 060e
at least one is different
both are different

sentData: ffff  sentAddr: 060c
at least one is different
at least one is equal

sentData: fb8c  sentAddr: 0000
at least one is different
at least one is equal

如您所见,输出不会显示不再存在。

由于我没有更改任何测试条件但仅更改了打印输出,因此必须遵循描述现在准确 wrt。 测试条件的实际含义

如果你想改写这个

if ((sentData == "ffff") && (sentAddr == "0000")) 
    cout << "both are equal" << endl;
else 
    cout << "at least one is different" << endl;

使用!=,您应按以下方式执行此操作:

if (!((sentData != "ffff") || (sentAddr != "0000"))) 
    cout << "both are equal" << endl;
else 
    cout << "at least one is different" << endl;

这是应用De Morgan's law的一个例子。

这两个

if (!((sentData == "ffff") && (sentAddr == "0000"))){
    // do stuff
}

// note: please use brackets consistently
if ((sentData == "ffff") && (sentAddr == "0000")) {
} else {
    // do stuff
}

可以改写为

if ((sentData != "ffff") || (sentAddr != "0000")){
    // do stuff
}

<强>附录:

您对问题的最后修改包括以下声明:

  

因此,如果我在sentData: fb8c sentAddr: 0000中使用if ((sentData != "ffff") && (sentAddr != "0000"))   我得到if (TRUE && FALSE),但仍然会输入if语句。

如果通过&#34;它仍然进入if语句&#34; 你的意思是它需要第一个分支,那么你错了。事实上,您的输出显示它打印&#34; B&amp;&amp;。相同&#34; ,这是第二个分支( else )。