按位运算符和逻辑运算符不会给出相同的结果

时间:2014-02-20 11:20:52

标签: c++ operators logical-operators

当我遇到一个使用按位运算符的例子时,我正在阅读C ++中的i / o系统,我在尝试时错误地放置逻辑运算符,结果不同。我不明白为什么会这样,

void main(){
    ios::fmtflags f;
    f = cout.flags();

    if(f & ios::showpos)
        cout << "showpos is set for cout. \n";
    else 
        cout << "showpos is cleared for cout. \n";

    cout << "setting showpos for cout. \n";
    cout.setf(ios::showpos);

    f = cout.flags();
    if(f & ios::showpos)
        cout << "showpos is set for cout. \n";
    else 
        cout << "showpos is cleared for cout. \n";

    cout << "clearing showpos for cout. \n";
    cout.unsetf(ios::showpos);

    f = cout.flags();
    if(f & ios::showpos)
        cout << "showpos is set for cout. \n";
    else 
    cout << "showpos is cleared for cout. \n";

    cout << "\n";

    f = cout.flags();

    if(f && ios::showpos)
        cout << "showpos is set for cout. \n";
    else 
        cout << "showpos is cleared for cout. \n";

    cout << "setting showpos for cout. \n";
    cout.setf(ios::showpos);

    f = cout.flags();
    if(f && ios::showpos)
        cout << "showpos is set for cout. \n";
    else 
        cout << "showpos is cleared for cout. \n";

    cout << "clearing showpos for cout. \n";
    cout.unsetf(ios::showpos);

    f = cout.flags();
    if(f && ios::showpos)
        cout << "showpos is set for cout. \n";
    else 
    cout << "showpos is cleared for cout. \n";
}

以下是结果,

showpos is cleared for cout.
setting showpos for cout.
showpos is set for cout.
clearing showpos for cout.
showpos is cleared for cout.

showpos is set for cout.
setting showpos for cout.
showpos is set for cout.
clearing showpos for cout.
showpos is set for cout.
Press any key to continue . . .

正确的结果是具有逐位运算符的结果,但为什么逻辑运算符错误?您如何知道编程时使用哪个运算符?

5 个答案:

答案 0 :(得分:2)

在这种情况下,f被用作位数组。您可以将任何基本类型视为位数组 - 例如,如果您的int是32位,那么它就像是一个大小为32的位数组。如何将1写入第4位?

f = f | 8

因为8的二进制表示是1000(即第四位)。你怎么写0到第四位?

f = f & ~8

这是因为~8将创建这样一个位数组,其中只有第四位为0.现在,要获得第四位的值,您将执行:

f & 8

如果第四位为1,则最后一个操作将返回8;如果第四位为0,则返回0。

然而,在布尔术语中,除0之外的任何内容都为真 - 并且只有0为假。这意味着如果你执行f & 8并将其强制转换为布尔值,那么只有当第四位为1时才会生效,而只有当第四位为0时才会生效。但是,如果执行f && 8只要f非零,结果就为真 - 因为8转换为布尔值为真。

答案 1 :(得分:1)

Madz,两个结果可能不同,因为两个运营商完全不同......

考虑一下,

int i = 10;
int j = 2;

if (10 & 4)   // will evaluate false

if (10 && 4)  // will evaluate true..

说明: 按位and运算符计算位。

10 =二进制1010 4 = 0100(二进制)

因此10&amp; 4结果0,相当于假。

在c或c ++中,0以外的任何东西都是真的,记住,
因此10&amp;&amp; 4,(即真&amp;&amp; true)评估为真......

希望能解决你的问题.. :)

答案 2 :(得分:1)

处理标志时,通常需要按位。这里的原因是你正在测试一个比特(或有时是多个比特)。除{1}外,ios::showpos值的所有位均为零。

当您对标志执行逐位&时,效果是隔离特定值。如果结果不为零,则设置标志。如果为零,则不设置标志。

当您使用逻辑&&时,您正在做一些与众不同的事情。您正在测试运算符的两边是否为真(非零)。如果是,那么结果也是如此。否则就是假的。

因此,当您执行if(f && ios::showpos)时,结果为真,因为fios::showpos都是非零值。

答案 3 :(得分:1)

假设您有两个值

int first  = 0x1;
int second = 0x2;

或使用二进制文字

int first  = 0b01;
int second = 0b10;

由于它们中的每一个都不等于零,所以表达式

first && second

将是真的。标量类型的非零值在逻辑表达式中隐式转换为true。

另一方面,如果你将使用表达式

first & second

在某些情况下,它总是等于false,因为设置的两个数字都没有公共位。在第一个数字中设置第一个数字,但在第二个数字中它等于零。在第二个数字中,第二个数字被设置,但在第一个数字中,它等于零。

所以

0b01
&
0b10
====
0b00

当结果等于零时,它将在逻辑表达式中转换为false。

答案 4 :(得分:0)

看看Madz的C ++问题,让我解释一下 c ++将所有整数视为除0以外的真值。所以当你尝试两个不同的表达式时,一个用“&amp;”和其他“&amp;&amp;”,c ++评估表达式true。例如。

int i=5;
int j = i>1 && i<10;  //j gets 1 here, being treated as true
int k = i>1 & i<10;   // here k also gets 1, because 1 AND 1 = 1

或者您可以将其视为

TRUE AND TRUE ---&gt; TRUE

是和否 - &gt; FALSE

我想你明白了。