C++ 具有多重条件的奇怪行为

C++ 具有多重条件的奇怪行为,c++,boolean-logic,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 <<

我注意到,在组合
时,我偶然发现了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 (!((sentData == "ffff") && (sentAddr == "0000"))) {
    // do stuff
}
工作错误:

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
因此,如果我在
if((sentData!=“ffff”)&&(sentAddr!=“0000”)
中使用
sentData:fb8c sentAddr:0000
,我得到
if(TRUE&&FALSE)
,但显然它仍然进入
if
语句

Q:有人知道为什么吗

我这样问是因为我不想写这样难看的代码:

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 (!((sentData == "ffff") && (sentAddr == "0000"))) {
    // do stuff
}


你认为
是错误的!a&&!b
相反!(a和b)

这是因为在布尔运算上分配或取消分配求反运算需要将布尔运算翻转为其对偶运算,并对各个内部项求反,反之亦然

这被称为,并且是布尔代数中的一条基本定律

因此,双重目的是:

(a && b)
(!a && !b)
实际上是:

(!a || !b)
(a || b)
以及:

(a && b)
(!a && !b)
实际上是:

(!a || !b)
(a || b)
以下是工作代码:

#include <iostream>
#include <string>

int main()
{
    using namespace std;

    std::string sentData("ffff");
    std::string sentAddr("060C");

    auto a = (sentData == "ffff");  // true
    auto b = (sentAddr == "0000");  // false

    if (a)              cout << "A 1. Same" << endl;
    else                cout << "A 1. Different" << endl;

    if (b)              cout << "A 2. Same" << endl;
    else                cout << "A 2. Different" << endl;

    if (a && b)         cout << "A &&. Same" << endl;
    else                cout << "A &&. Different" << endl;

    if (!a)             cout << "B 1. Different" << endl;
    else                cout << "B 1. Same" << endl;

    if (!b)             cout << "B 2. Different" << endl;
    else                cout << "B 2. Same" << endl;

    if ((!a || !b))     cout << "B &&. Different" << endl;
    else                cout << "B &&. Same" << endl;
}
#包括
#包括
int main()
{
使用名称空间std;
std::字符串sentData(“ffff”);
std::字符串sentAddr(“060C”);
自动a=(sentData==“ffff”);//为真
自动b=(sentAddr==“0000”);//错误

如果(a)不能因为你似乎仍然有点困惑,我将尝试一种不同于@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;
如您所见,输出不再显示不一致

由于我没有更改任何测试条件,只是更改了打印输出,因此说明现在必须是准确的,即测试条件的实际含义


如果你想重写这个

if ((sentData == "ffff") && (sentAddr == "0000")) 
    cout << "both are equal" << endl;
else 
    cout << "at least one is different" << endl;
这是一个应用的例子


这两个

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
}

附录:

您对问题的最后一次编辑包括以下声明:

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


如果“它仍然进入If语句”,您的意思是它接受第一个分支,那么您就错了。事实上,您的输出显示它打印“B&&.Same”,这是第二个分支(else)。

因此,基本上您想知道为什么
x!=a&&x!=B
的行为与
!(x==a | x==B)
?…绘制真值表并思考一下,因为它是正确的。或者是其他问题吗?检查德摩根定律()。
!(a&b)==(!a | |!b)
“理论上,我认为它应该产生相同的结果”你能解释一下你为什么这么想吗?@king_nak:请不要在评论部分回答。不,不,你不理解我。我是说在上一篇
if
陈述
“B&&&.Different”如果带有
!=
符号的条件之一为真,则打印
。但仅当这两个条件都为真时,才应打印它。例如:
如果((sentData不等于“ffff”)和(sentAddr不等于“0000”){do stuff…}
那么这是德摩根定律还是其他什么?@deviantfan,不,这不是我想知道的。@Lightness在轨道上比赛,希望我现在能解释得更多一些(我也更新了原来的问题)我现在明白了…不知道我怎么会瞎了那么长时间。谢谢!我会投票给两个答案,但遗憾的是,由于声誉的限制,我不能。再次感谢你!