2011-10-20 48 views
6

也许问题就是这么简单...在枚举和位操作

有一个枚举定义:

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) 

当这条件是真的,当它不是?

回答

14

最终,该代码正在检查uop->flags变量中是否打开单个位(FCTRL标志)。

但这里有一些解释:

含蓄,代码if(X)检查对于X是“真”。 对于整数,0是唯一的“假”值,其他都是“真”。

因此你的代码就相当于:

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

现在,这是什么意思?

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

因此,如果我们以二进制写了我们两个操作数:

uop->flags  1010 1010 (example) 

FCTRL   0100 0000 

在这个例子中,如果执行“和”每对位,你得到的结果是:

result   0000 0000 

其中,计算结果为false,实际上在该示例中uop->flags值没有设置FCTRL标志。

现在,这里是另一个例子,该标志集:

uop->flags  1110 1010 (example) 

FCTRL   0100 0000 

相应相与结果:

result   0100 0000 

这个结果不为零,因此 “真”,引发你if声明。

1

当在uop-> flags中设置与FCTRL(0x040)对应的位时,条件成立。 '&'是一个按位与屏蔽除FCTRL设置的位外的所有位。

+0

uop-> flags = 0x140 =>是否为真? – mahmood

+0

是因为0x140&0x040的结果是0x040。 – Lou

+0

有关按位运算的更多详细信息,请参见http://en.wikipedia.org/wiki/Bitwise_operation。 – Lou

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 ==二进制01000000.

+0

如果我想检查FRET是否设置,我应该怎么做? – mahmood

+0

@mahmood:'if(uop-> flags&FRET){/ * FRET is set * /}' – Jon

0

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

0

由于枚举类型使用二进制数字的位置(即单位,2,4,8,16等),并且该操作执行逻辑和。如果该位置位,则该值不会为零(真),否则将为假。

0

在这种情况下,每一个下一枚枚举项都会左移一位,因此检查一下是否设置了某个标志是合法的,只需检查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!