C++ 关于枚举和位运算
也许问题很简单 有一个枚举定义:C++ 关于枚举和位运算,c++,c,bit-manipulation,enumeration,C++,C,Bit Manipulation,Enumeration,也许问题很简单 有一个枚举定义: enum uop_flags_enum { FICOMP = 0x001, FLCOMP = 0x002, FFCOMP = 0x004, FMEM = 0x008, FLOAD = 0x010, FSTORE = 0x020, FCTRL = 0x040, FCALL = 0x080,
enum uop_flags_enum {
FICOMP = 0x001,
FLCOMP = 0x002,
FFCOMP = 0x004,
FMEM = 0x008,
FLOAD = 0x010,
FSTORE = 0x020,
FCTRL = 0x040,
FCALL = 0x080,
FRET = 0x100,
FCOND = 0x200
};
代码中的某个地方有:
if (uop->flags & FCTRL)
当此条件为真且不为真时?当在uop->flags中设置与FCTRL(0x040)对应的位时,此条件为真。&'是按位屏蔽,实际上屏蔽除FCTRL设置的位以外的所有位 这是一个枚举,用于为操作定义多个“标志”。您可以通过每个定义的值都是2的精确幂这一事实来推断这一点,因为它由一个值的单个位(“标志”)表示 此类型枚举的优点是,您可以使用以下命令组合任意多个标志: 你给出的条件,它使用
当且仅当设置了
FCTRL
标志时,即当设置了uop->flags
的第7位时,为真。这是因为FCTRL==0x040==binary 01000000。设置位时,条件为真。0x40是1000000,因此当设置标志中的第7位时,它将为真。最终,此代码检查uop->flags
变量中是否启用了单个位(FCTRL标志)
但这里有一些解释:
如果(X)
检查X是否为“真”值,则代码if(X)
会隐式地进行检查。
对于整数,0是唯一的“假”值,其他所有值都是“真”
因此,您的代码相当于:
if(0!=(uop->flags&FCTRL))
那是什么意思
&
运算符执行“按位AND”,这意味着左侧的每个位与右侧的相应位进行AND运算
如果我们用二进制写出两个操作数:
uop->flags 1010 1010 (example)
FCTRL 0100 0000
在本例中,如果对每对位执行“和”,则会得到以下结果:
result 0000 0000
其计算结果为false,在该示例中,uop->flags
值未设置FCTRL标志
下面是另一个示例,其中设置了标志:
uop->flags 1110 1010 (example)
FCTRL 0100 0000
相应的ANDed结果:
result 0100 0000
此结果为非零,因此为“true”,触发您的
if
语句。因为枚举类型使用二进制数字的位置(即单位、2、4、8、16等),并且操作执行逻辑和。如果设置了该位,则该值将不会为零(true),否则将为false。在这种情况下,每个下一个枚举项将左移1位,因此,只需检查变量&flag==true
即可检查是否设置了某些标志。然而,如果我们想设置多位标志模式呢?比如说-
enum {
#ifdef __GNUC__ // cool in GCC we can use binary constants
myFlag = 0b1010
#else // otherwise fallback into integral constant mode
myFlag = 10
#endif
}
何时如何检查变量X是否设置了此标志?我们不能就这么做
X&myFlag==true
,因为例如0b1000&myFlag==true
和0b010&myFlag==true
——但0b1000和0b010都没有设置我们的两位!出于这个原因,我更喜欢完全检查位掩码,它允许在枚举中定义多位模式:
#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)
嗯 uop->flags=0x140=>条件是否为真?有关按位操作的更多详细信息,请参阅。如果我想检查是否设置了FRET,我应该怎么做?@mahmood:
如果(uop->flags&FRET){/*FRET设置了*/}
enum {
#ifdef __GNUC__ // cool in GCC we can use binary constants
myFlag = 0b1010
#else // otherwise fallback into integral constant mode
myFlag = 10
#endif
}
#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)