C++ 为什么按位OR和逻辑不能按预期工作?
我有下面的示例代码。我一直认为,对枚举值执行按位或,将允许我检查结果(使用按位和),以查看哪些枚举值包含在结果中,哪些不包含在结果中 例如,如果我做了C++ 为什么按位OR和逻辑不能按预期工作?,c++,c++11,enums,bitwise-operators,C++,C++11,Enums,Bitwise Operators,我有下面的示例代码。我一直认为,对枚举值执行按位或,将允许我检查结果(使用按位和),以查看哪些枚举值包含在结果中,哪些不包含在结果中 例如,如果我做了result=mouse |耳机,那么我可以再次检查result&mouse==mouse,作为条件,以了解鼠标是否包含在结果中。但是无论我用什么&产生结果,比如说X,我总是以X结束。为什么 在下面的代码中,我认为if应该失败,因为options中没有包含straw,但它没有 #include <iostream> #include &
result=mouse |耳机
,那么我可以再次检查result&mouse==mouse
,作为条件,以了解鼠标
是否包含在结果
中。但是无论我用什么&
产生结果,比如说X,我总是以X结束。为什么
在下面的代码中,我认为if应该失败,因为options
中没有包含straw
,但它没有
#include <iostream>
#include <iomanip>
using namespace std;
enum Stock
{
milk,
choclate,
tv,
cable,
mouse,
fan,
headphone,
cup,
straw,
pen,
candy,
glasses,
book,
plug
};
int main()
{
Stock options = static_cast<Stock>( static_cast<int>(mouse) | static_cast<int>(headphone)
| static_cast<int>(cup) | static_cast<int>(pen) );
if ((static_cast<int>(loptions)) & (static_cast<int>(straw)) == static_cast<int>(straw))
{
cout << "bring straw!" << endl;
}
system("PAUSE");
return 0;
}
要将枚举用作位集(或标志),您需要确保每个枚举值的二进制表示形式正好包含一个设置为1的位。换句话说,每个枚举值必须是2的幂。例如:
enum Stock
{
milk = 1, // 0b0001
choclate = 2, // 0b0010
tv = 4, // 0b0100
cable = 8 // 0b1000
// etc.
};
否则,位逻辑运算符将无法区分某些值和其他值的某些组合。在原始代码中,tv
和cable
的值分别为1
、2
和3
。在二进制中,即01
、10
和11
。ORing巧克力
和电视
产生的11
(0b01 | 0b10==0b11
),其值与电缆
相同。巧克力
和电视
的组合与电缆
标志无法区分
<>但是C++提供了。此类允许您以类似于位数组的方式轻松操作位集。然后,您可以使用原始枚举并将每个枚举值用作位的索引。您假设每个
枚举的值都是唯一的位。事实并非如此<代码>枚举
s值始终比上一个枚举值高1,除非另有规定。@LambaDawet是的,但唯一值并不意味着唯一的不同位。唯一位意味着需要使用值1、2、4、8等。例如,这里的cable==tv | chocolate
milk
为零,在1处甚至没有任何位。可能您对二进制AND和OR运算符的工作原理感到困惑。要进行位检查,要一起或(并用AND检查)的不同参数不应该都是2的幂(即1,2,4,8,…),而不是线性范围0,1,2,3,4,5吗?(与@FrançoisAndrieux的评论一致)您的编辑将括号放错了。如果((options&cup)==cup),则写入就足够了,静态转换是无用的。但重要的是要执行(options&cup)==cup
,而不是options&(cup==cup)
我像您那样添加了值,如果我像执行if(对于cup)
一样执行if(对于cup)
,它会忽略这两条语句,并且不会显示任何内容。您能检查一下吗?@LambaDawet我得到了一个“&”:检查运算符优先级是否有可能出错;在我尝试您的代码时,请使用括号澄清优先级”警告。=
发生在&
之前。可以在方程式左侧使用括号来解决此问题。但一个更简单的解决办法是完全消除平等。如果x
与y
有任何共通位,则仅x&y
将产生true。无需与y
进行比较。明白了!再次感谢!“ORing巧克力和电视产生11(0b01 | 0b10==0b11),这与有线电视的值相同。”-这是错误的@我想详细说明一下吗?
enum Stock
{
milk = 1, // 0b0001
choclate = 2, // 0b0010
tv = 4, // 0b0100
cable = 8 // 0b1000
// etc.
};