2010-10-13 2 views
111

Существует переменная, которая содержит несколько флагов, и я хочу удалить один из них. Но я не знаю, как его удалить.Как удалить флаг в C?

Вот как я установил флаг.

my.emask |= ENABLE_SHOOT; 
+5

Вы можете найти ответы на вопрос SO [«Как установить, очистить и переключить один бит в C»] (http://stackoverflow.com/questions/47981/how-do-you-set- clear-and-toggle-a-single-bit-in-c). – schot

ответ

266

Короткий ответ

Вы хотите сделать Bitwise AND операцию по текущему значению с Bitwise NOT работы флага вы хотите сбросить. Побитовое НЕ инвертирует каждый бит (т. Е. 0 => 1, 1 => 0).

flags = flags & ~MASK; или flags &= ~MASK;.

Длинного ответ

ENABLE_WALK = 0 // 00000000 
ENABLE_RUN = 1 // 00000001 
ENABLE_SHOOT = 2 // 00000010 
ENABLE_SHOOTRUN = 3 // 00000011 

value = ENABLE_RUN  // 00000001 
value |= ENABLE_SHOOT // 00000011 or same as ENABLE_SHOOTRUN 

При выполнении побитового И с Поразрядным не значением, которое вы хотите неустановленными.

value = value & ~ENABLE_SHOOT // 00000001 

вы фактически делаете:

 0 0 0 0 0 0 1 1  (current value) 
    & 1 1 1 1 1 1 0 1  (~ENABLE_SHOOT) 
     --------------- 
     0 0 0 0 0 0 0 1  (result) 
+0

@ Аарон: Я рад, что это помогло. У меня изначально были проблемы с поразрядными операциями * до тех пор, пока кто-то не потратил 10 минут, чтобы объяснить это на бумаге. – Dennis

+1

@Dennis Я думал, что XOR будет работать, чтобы удалить уже установленный флаг. 'notification.sound^= Notification.DEFAULT_SOUND;' – likejiujitsu

+3

Как вы разрешаете Walk? Так как X | 0 == X – Unikorn

69
my.emask &= ~(ENABLE_SHOOT); 

очистить несколько флагов:

my.emask &= ~(ENABLE_SHOOT|SOME_OTHER|ONE_MORE); 
10

Важно отметить, что если переменная манипулируют больше, чем INT, значение, используемое в «а не» выражение должно быть хорошо. Фактически, иногда можно избежать использования меньших типов, но есть достаточно странных случаев, что, вероятно, лучше всего использовать суффиксы типа, чтобы убедиться, что константы достаточно велики.

+4

+1 для ловли неочевидного углового случая. Один из способов избежать этого - вместо этого использовать 'flags - = flags & MY_FLAG;' (или '^ =', если хотите). –

+1

@R .. Я бы использовал '^ =', за исключением того, что он будет переключаться между битами, и иногда вы можете не знать, какой из многих флагов установлен. Если я хочу убедиться, что два правильных бита равны нулю, , например. my.emask: '0 1 0 1' вход: '0 0 1 1' с: '^ =' '0 1 1 0' с: '& ~' '0 1 0 0' – Hector

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