2010-08-19 4 views
25

У меня есть объявление перечисления с использованием битовых флагов, и я не могу точно понять, как это использовать.Как использовать перечисления с битовыми флагами

enum 
{ 
    kWhite = 0, 
    kBlue = 1 << 0, 
    kRed  = 1 << 1, 
    kYellow = 1 << 2, 
    kBrown = 1 << 3, 
}; 
typedef char ColorType; 

Я полагаю, хранить несколько цветов в одном colorType я OR биты вместе?

ColorType pinkColor = kWhite | kRed; 

Но предположим, что я хотел бы проверить, если pinkColor содержит kRed, как бы я это сделать?

Любой, кто хотел бы привести пример, используя предоставленный пример ColorType?

ответ

32

Да, использование побитовое ИЛИ (|), чтобы установить несколько флагов:

ColorType pinkColor = kWhite | kRed; 

Затем с помощью побитового И (&), чтобы проверить, если флаг установлен:

if (pinkColor & kRed) 
{ 
    // do something 
} 

Результат & имеет любой бит, только если тот же бит установлен в как операндов. Поскольку единственный бит в kRed - бит 1, результат будет равен 0, если другой операнд также не имеет этого бита.

Если вам нужно получить, является ли конкретный флаг установлен как BOOL, а не только тестирование его в if состоянии сразу, сравнить результат побитового И к тестируемой бит:

BOOL hasRed = ((pinkColor & kRed) == kRed); 
+18

Примечание: Это означает, что если 'pinkColor' является' kRed', '(pinkColor & kRed)' будет оцениваться 'kRed', * not * 1 или' YES'! Это может быть ошибкой при назначении небольшому типу, например 'BOOL': если значение равно 1 << (количество бит в' BOOL') или больше, оно будет вне диапазона. Общим решением является сравнение результата с тестируемым битом: «BOOL isPink = ((pinkColor & kRed) == kRed);« Альтернативой является передача результата в тип «bool» C99: 'isPink = (bool) (pinkColor & kRed); 'И (по общему признанию, необычный) способ, который не предполагает, что 1 находится в диапазоне, будет использовать'?: ':' isPink = (pinkColor & kRed)? ДА: НЕТ; ' –

+0

@PeterHosey Соответствующее дальнейшее чтение для всех, кто интересуется вашим комментарием: http://www.bignerdranch.com/blog/bools-sharp-corners/. Кстати, если кто-то смущен (как и я) о том, почему на самом деле кастинг на C99 'bool' вместо' BOOL' исправляет проблему, ответ заключается в том, что приведение к 'bool' является магии, как описано в http: //stackoverflow.com/questions/16934876/magic-of-casting-value-to-bool. Краткая версия: 'bool' - это псевдоним' _Bool', а в стандарте C99 говорится: «Когда любое скалярное значение преобразуется в _Bool, результат равен 0, если значение сравнивается с с 0, в противном случае результат равен 1 . "* –

Смежные вопросы