2011-10-20 77 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!