2013-04-17 3 views
11

Что означает if ((a & b) == b) в следующем блоке кода?Что означает это выражение в C#?

if ((e.Modifiers & Keys.Shift) == Keys.Shift) 
{ 
    lbl.Text += "\n" + "Shift was held down."; 
} 

Почему это не так?

if (e.Modifiers == Keys.Shift) 
{ 
    lbl.Text += "\n" + "Shift was held down."; 
} 
+4

Google «побитовое И», а затем «бит-флаг Google». – mbeckish

+0

Возможный дубликат [Что делает сингл | или означает?] (http://stackoverflow.com/questions/9736751/what-does-a-single-or-mean) –

ответ

17

Если вы посмотрите Keys enum, это flag enum с атрибутом [FlagsAttribute].

Использовать собственный атрибут FlagsAttribute для перечисления, только если побитовое действие (И, ИЛИ, ЭКСКЛЮЗИВ ИЛИ) должно выполняться по числовому значению.

Определить константы перечисления в силах двух, то есть 1, 2, 4, 8 и т. Д. Это означает, что отдельные флаги в комбинированных константах перечисления не перекрываются.

Так e.Modifiers может быть комбинацией более одного перечисления:

e.Modifiers = Keys.Shift | Keys.Cancel | Keys.Enter 

Просто очень простое предположение объяснить понятие:

Keys.Shift : 001 (1) 
Keys.Cancel : 010 (2) 
Keys.Enter : 100 (4) 

Итак:

e.Modifiers = Keys.Shift | Keys.Cancel | Keys.Enter equal 001 | 010 | 100 = 111 

И условие:

e.Modifiers & Keys.Shift equal 111 & 001 = 001 

это означает:

e.Modifiers & Keys.Shift == Keys.Shift 

если e.Modifiers не содержит Keys.Shift:

e.Modifiers = Keys.Cancel | Keys.Enter (110) 

Так что результат будет:

e.Modifiers & Keys.Shift equals 110 & 001 = 000 (is not Keys.Shift) 

Для отстойник вверх, это условие проверяет er e.Modifiers содержит Keys.Shift или нет

+1

'010 & 001' равен' 0' –

+0

@MattBurland: Чинги, чтобы указать, отредактировал –

3

Один амперсанд (&) поразрядное И, поэтому, в основном, при добавлении значения (в & б), а затем проверить на равенство в (а & б) == б

Так в вашем примере, в основном, говорят, что нажата клавиша shift (любая клавиша + сдвиг) == shift.

+2

Это не их добавление! Существует огромная ** разница между применением побитового оператора И и добавлением. – antonijn

+0

Да, я это понимаю. Я просто пытался объяснить это простым способом. Извините, что обидел. –

5

Это логическая логика (& = "побитовая и"). Вы проверяете, содержит ли переменная значение. Это похоже на фильтр.

Exemple:

a -> 00110011 
b -> 00000011 
a&b -> 00000011 

В коде

if ((e.Modifiers & Keys.Shift) == Keys.Shift) 

, который проверяет Keys.Shift содержится в e.Modifiers.

4

Один амперсанд относится к bitwise AND operator. При использовании в сочетании с перечислением, имеющим на нем атрибут [Flags], который перечисляет enum Keys, он используется, как вы показали, чтобы определить, установлен ли один из битов этого перечисления или нет.

Одновременно может быть нажата более одной клавиши-модификатора, поэтому она используется вместо прямого сравнения.

Подробнее об enum flags here. Прокрутите вниз до подраздела под названием «Типы перечислений в виде бит-флагов». Вы увидите образец, который очень похож на этот.

3

& является побитовое И оператор. То, что он делает, это Keys - это перечисление флага, значения в Keys могут быть поразрядными комбинациями из нескольких значений. Таким образом, чтобы проверить какое-либо конкретное значение, вы сначала И ваше значение со значением, которое хотите проверить, а затем сравните его со значением, которое вы хотите проверить.

Например, вы могли бы как сдвиг и клавишу Ctrl в нажатом состоянии, так что значение e.Modifier будет поразрядное сочетание Keys.Shift и Keys.Ctrl. Таким образом:

e.Modifier == Keys.Shift 

Неверно. Shift удерживается нажатой, но Ctrl также удерживается нажатой. Если вы хотите узнать, удерживается ли Shift независимо от того, какие другие клавиши могут быть удержаны, вам нужно сначала отфильтровать все остальные ключи.Это легко сделать с помощью Keys.Shift в качестве фильтра:

(e.Modifier & Keys.Shift) == Keys.Shift 

Теперь это будет справедливо, если клавиша переключения удерживается независимо от того, что других ключей могут быть нажата и ложь в противном случае.

3

Часть 1

Это логика и оператор.

Он используется, когда несколько флагов должны быть устанавливаемыми в одном например Integer:

а, для примера 3, что означает 00000011 в двоичной системе счисления. b, например, 2, что означает 00000010 в двоичной записи.

Если вы хотите, чтобы проверить, если есть флаг (второй бит справа), который б представляет собой набор использовать и оператор:

& б = 00000010

И когда это равно Ь (или> 0), вы знаете, что флаг установлен.

Часть 2

Равное оператор также может быть использован в случае, вы хотите проверить, если «Keys.Shift» является единственным ключом «модификатор» и никакой другой один не будет нажата. Когда вы используете первый код, могут быть нажаты и другие клавиши «модификатор», и условие if будет по-прежнему истинным.

3

Один амперсанд (&) выполняет побитную операцию И; двойной амперсанд (& &) выполняет логическую операцию И.

Побитно и выполняет операцию И на каждом бите обоих аргументов (следовательно, он называется «бит-мудрый»). Таким образом, вывод битовой операции И (или любой побитовой операции) не будет логическим значением. Вот некоторые примеры побитового И операции:

1001 & 0001 = 0001 
1101 & 1111 = 1101 

Логическое И работает на двух логических значений и возвращает логическое значение:

true && true = true 
false && true = false 

короткое замыкание
Булева операция И (& &) также могут быть выполнены на двух выражениях, которые возвращают логическое значение:

int a = 5; 
int b = 10; 
bool result = (a < 3) && (b > 3); 
// result will be false; 

Так как первое выражение принимает значение (a < 3)false, результат не может быть true, потому что оба выражения должны оценить, чтобы true для того, чтобы в результате быть true. Из-за этого второе выражение даже не будет оценено. Это называется «короткое замыкание». Тем не менее, с помощью бит-операции И, оба выражения должны быть оценены до выполнения операции. Таким образом, в большинстве ситуаций, когда вы просто хотите определить, истинны ли две вещи (логические), логический И (& &) будет лучшим вариантом.

В вашем примере код сравнивает отдельные биты в пределах e.Modifiers с отдельными битами в Keys.Shift. Ни один из аргументов не представляет собой логическое значение, и, следовательно, операция побито (&), а не boolean (& &).

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