在枚举和按位操作

时间:2011-10-20 18:50:55

标签: 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,  
  FRET          = 0x100, 
  FCOND         = 0x200  
};

代码中的某处有:

if (uop->flags & FCTRL)

当这个条件为真时,它不是吗?

6 个答案:

答案 0 :(得分:14)

最终,此代码检查uop->flags变量中是否打开了一个位(FCTRL标志)。

但是这里有一些解释:

隐式地,代码if(X)检查X是否为“真”值。 对于整数,0是唯一的“假”值,其他一切都是“真”。

因此,您的代码相当于:

if (0 != (uop->flags & FCTRL))

现在,这是什么意思?

&运算符执行“按位AND”,这意味着左侧的每个位与右侧的相应位进行AND运算。

所以如果我们用二进制写出我们的两个操作数:

uop->flags      1010 1010  (example)

FCTRL           0100 0000

在此示例中,如果对每对位执行“AND”,则得到结果:

result          0000 0000

评估为false,实际上在该示例中uop->flags值没有设置FCTRL标志。

现在这是另一个例子,其中标志设置:

uop->flags      1110 1010  (example)

FCTRL           0100 0000

相应的ANDed结果:

result          0100 0000

此结果为非零,因此为“true”,触发您的if语句。

答案 1 :(得分:5)

这是一个枚举,用于为操作定义许多“标志”。您可以通过以下事实推断出这一点:每个定义的值都是2的精确幂,因此由值的单个位(“标志”)表示。

此类枚举的优点是您可以使用bitwise OR组合任意数量的标志:

uop->flags = FMEM | FLOAD | FRET; // sets the three corresponding flags

您提供的条件,使用bitwise AND

uop->flags & FCTRL
当且仅当FCTRL标志置位时,即uop->flags的第7位置位时,

才为真。这是因为FCTRL == 0x040 == binary 01000000。

答案 2 :(得分:1)

当在uop->标志中设置与FCTRL(0x040)对应的位时,条件为真。 '&安培;'是按位AND有效屏蔽所有位,但是由FCTRL设置的位。

答案 3 :(得分:0)

当该位置位时,条件为真。 0x40是1000000,所以当flags中的第7位置位时 - 它将为真。

答案 4 :(得分:0)

由于枚举类型正在利用二进制数字的位置(即单位,2,4,8,16等),并且操作执行逻辑和。如果设置了该位,则该值不为零(true),否则为false。

答案 5 :(得分:0)

在这种情况下,每个下一个枚举项都向左移1位,因此通过检查是否variable & 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 == true0b0010 & myFlag == true - 但0b1000和0b0010都没有设置我们的TWO位!出于这个原因,我更喜欢完全检查位掩码,以便在枚举中定义多位模式:

#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)

HTH!