简单的布尔运算符用于位标志

9

我希望能了解更多关于这方面的知识,以便在我的项目中实现。

目前我已经有了基本的了解:

unsigned char flags = 0; //8 bits

flags |= 0x2; //apply random flag

if(flags & 0x2) {
   printf("Opt 2 set");
}

现在我希望做一些更复杂的事情,我想要做的是像这样应用三个标志:

flags = (0x1 | 0x2 | 0x4);

然后从中删除标志0x10x2?我认为可以通过应用按位NOT(并通过按位AND应用它)来执行类似以下的操作:

flags &= ~(0x1 | 0x2);

显然,无论如何,当我检查时它们仍然存在。

我也不知道如何检查它们是否不存在于位标志中(因此我无法检查我的先前代码是否有效),这应该是什么样子?

if(flags & ~0x2) 
    printf("flag 2 not set");

我最近的搜索中没有找到任何与此相关的资源,但我愿意学习并将其教给他人,我对此非常感兴趣。如果这很困惑或简单,我很抱歉。

2个回答

23
并将其减去两个?我认为我可以这样做:
flags &= ~(0x1 | 0x2);

这是删除标志的正确方法。如果在该行之后使用printf("%d\n", flags),输出应该为4

我也不知道如何检查位标志中是否不存在它们(因此无法检查我的先前代码是否有效),类似于这样吗?

if(flags & ~0x2) 
    printf("flag 2 not set");
不行:
if ((flags & 0x2) == 0)
    printf("flag 2 not set");

编辑:

为了测试多个标志的存在:

if ((flags & (0x1 | 0x2)) == (0x1 | 0x2))
    printf("flags 1 and 2 are set\n");

为了测试多个标志位的缺失,只需像以前一样与0进行比较:

if ((flags & (0x1 | 0x2)) == 0)
    printf("flags 1 and 2 are not set (but maybe only one of them is!)\n");

没问题。位运算符很有趣。 :) - cdhowie
现在我该如何检查两个标志是否被设置,而不使用布尔运算符呢?例如 if(flags & (0x1 | 0x2)),但是这似乎即使我只设置了 0x1 也能工作。 - John
1
这回答了我所有的问题,还有更多,我为此感到非常高兴。再次感谢你。 :) - John
没问题,这就是我在这里的原因。;) - cdhowie

11

我不确定为什么您认为清除操作不起作用。

flags &= ~(0x1 | 0x2);

以下是正确的方法。用于检查位未设置的操作是:

if (!(flags & 0x2)) ...

你现在拥有的:

if (flags & ~0x2) ...

如果任何其它位被设定,它将会是真的,这可能就是为什么您认为清除操作不起作用的原因。问题不在于清除而在于检查。

如果你想检查一个组中的所有位是否被设置:

if ((flags & (0x2|0x1)) == 0x2|0x1) ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接