2010-09-04 84 views
8

最近我遇到了幾個C和C++中的「flags」的例子,我不太明白它們是如何工作的。看一些源代碼後,我發現經常標誌值以十六進制定義如下所示:標誌如何在C中工作?

FLAG1 = 0x00000001, 
FLAG2 = 0x00000010, 

我的直覺認爲,這些價值被組合。標誌是否將所有標誌值組合成一個int?如果我已經使用了這兩種像FLAG1 | FLAG2那麼結果是0x00000011

我需要與位偏移創建枚舉或者我可以使用的遞增整數像:

​​

回答

20

您需要抵消這些位,否則無法提取各個標誌。如果您的標記對應於1,2,3,& 4,並且組合值爲5,您如何判斷它是否爲2 & 3或1 & 4?

你也可以這樣來做,例如:

enum { 
    FIRST = 1 << 0, // same as 1 
    SECOND = 1 << 1, // same as 2, binary 10 
    THIRD = 1 << 2, // same as 4, binary 100 
    FOURTH = 1 << 3 // same as 8, binary 1000 
}; 

然後你把國旗像這樣:

int flags = FIRST | THIRD | FOURTH; 

你提取它們是這樣的:

if (flags & THIRD) { ... 
+0

謝謝你,這是非常直接的,你贏了。 – 2010-09-04 19:34:06

+3

*你贏了* - 真的嗎?如果發佈一個好的答案,我會說**每個人**勝。我*真的*希望FIRST,SECOND等僅僅是不好的示例名稱,並不是建議將這些常量聲明爲一次並重用它們。 'x = SECOND | FOURTH'不像'x = TEXTUREFLAGS_POINTSAMPLE |那樣可讀TEXTUREFLAGS_TRILINEAR'。 – 2010-09-04 19:58:53

+1

「你贏了」,如「謝謝」「很好的回答,」我接受你的回答「,我想這個命名是暗示的 – 2013-08-08 21:14:41

6

你的第一個方法是不是最有效的方式使用該位。在第一示例中使用的是十六進制表示法,它是等效於:

TEXTUREFLAGS_POINTSAMPLE = 1, 
TEXTUREFLAGS_TRILINEAR = 16, 

在看來你只是通過每次增加一第二種方法。組合標誌時這不起作用,因爲組合值可能與另一個標誌相同(例如,1 | 2 == 3)。

你應該使用這些值:

0x00000001 // == 1 
0x00000002 // == 2 
0x00000004 // == 4 
0x00000008 // == 8 
0x00000010 // == 16 
0x00000020 // == 32 
0x00000040 // == 64 
etc... 

這是兩個權力,他們可以使用組合按位或在沒有給出任何碰撞的方式。

+0

好吧,但它不會工作,如果我只做一個喜歡20會嗎?我仍然必須錯開十六進制,以免它們互相覆蓋對方?或者我不明白它是如何工作的。 – 2010-09-04 19:30:28

+1

@ user425756,如果你不使用兩個冪,你不能區分被設置的1和2之間的區別,或者3被設置。 – 2010-09-04 19:33:33

+0

是的,這就是我在想什麼。 – 2010-09-04 19:39:40

4

像這樣的標誌是二進制值,所以你可以在一個字節中組合1,2,4,8,16,32,64,128,或者將2的冪次加到2^31i一個int。因爲它們是二進制值,所以你可以將它們「或」放在一起,所以如果你「或」在一起1,2,4,你最終會得到7。而且你可以使用「和」來提取你想要的位 - 所以如果你有一個帶有一些標誌的int或者一起,並且你想看看是否設置了「4」位,那麼你可以說if (flag & 4)這將是真實的如果「4」位被設置。 (基於零的其中bitIndex處,所以0 - 31)

+0

謝謝你,這樣做更有意義。 – 2010-09-04 19:33:44

2

標誌看作32個比特的陣列(布爾值)

要打開你OR它這些位中的一個具有1 < < bitIndex處 要關閉一個關閉你和它與〜(1 < < bitIndex處) 要檢查它是否開啓或關閉你和它與(1 < < bitIndex處)

一旦你熬過之間的數字或/和反對邏輯的區別或/和它會全部點擊。 然後你會欣賞十六進制符號!