2013-04-17 1 views
11

Cosa significa "if ((a & b) == b)" nel seguente blocco di codice?Cosa significa questa affermazione in C#?

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

Perché non è così?

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

Google 'bit bit AND', quindi google' bit flag'. – mbeckish

+0

possibile duplicato di [Cosa fa un singolo | o & significa?] (http://stackoverflow.com/questions/9736751/what-does-a-single-or-mean) –

risposta

17

Se si dà un'occhiata Keys enum, questo è flag enum con attributo [FlagsAttribute].

Utilizzare l'attributo personalizzato FlagsAttribute per un'enumerazione solo se un'operazione bit per bit (AND, OR, OR ESCLUSIVO) deve essere eseguita su un valore numerico.

Definire le costanti di enumerazione in potenza di due, ovvero 1, 2, 4, 8 e così via. Ciò significa che i singoli flag nelle costanti di enumerazione combinate non si sovrappongono.

Quindi e.Modifiers potrebbe essere una combinazione di più di un enum:

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

Basta molto semplice ipotesi per spiegare il concetto:

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

Quindi:

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

E la condizione:

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

significa:

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

se e.Modifiers non contiene Keys.Shift:

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

Così il risultato sarà:

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

Per coppa up, questa condizione controlla chi er e.Modifiers contiene Keys.Shift oppure no

+1

'010 & 001' è uguale a' 0' –

+0

@MattBurland: Grazie per sottolineare –

3

Un singolo commerciale (&) è un AND bit per bit, quindi è fondamentalmente aggiungendo i valori di (a & b) e poi prova per l'uguaglianza in (a & b) == b

Così nel tuo esempio, sta praticamente dicendo se il tasto shift è premuto (qualsiasi tasto + shift) == shift.

+2

Non li aggiunge! C'è una differenza ** enorme ** tra l'applicazione dell'operatore AND bit a bit e l'aggiunta. – antonijn

+0

Sì, me ne rendo conto. Stavo solo cercando di spiegarlo in un modo semplice. Mi dispiace di offendere. –

5

È una logica booleana (& = "bit per bit e"). Controlla se la variabile contiene un valore. È come un filtro.

Esempio:

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

Nel codice

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

che controlla Keys.Shift è contenuto in e.Modifiers.

4

Una singola e commerciale si riferisce allo bitwise AND operator. Se utilizzato insieme a un enum che contiene l'attributo , che fa l'enumerazione Keys, viene utilizzato come indicato per determinare se uno dei bit di quell'enumerazione è impostato o meno.

Ci potrebbe essere più di un tasto modificatore premuto contemporaneamente, ecco perché viene usato al posto di un confronto diretto.

Ulteriori informazioni sulle bandiere enum here. Scorri verso il basso fino alla sottosezione "Tipi di enumerazione come flag di bit". Vedrai un esempio abbastanza simile a questo.

3

& è il bit a bit operatore AND. Quello che sta facendo è Keys è un flag enum, i valori in Keys possono essere una combinazione bit per bit di diversi valori. Quindi, per testare per qualsiasi valore specifico prima E il tuo valore con il valore che vuoi testare e poi confrontarlo con il valore che vuoi testare.

Per esempio, si potrebbe avere sia lo spostamento e il tasto CTRL premuto, quindi il valore di e.Modifier sarà una combinazione bit per bit di Keys.Shift e Keys.Ctrl. Quindi:

e.Modifier == Keys.Shift 

È falso. Shift viene tenuto premuto, ma anche Ctrl viene tenuto premuto. Se vuoi sapere se Shift viene tenuto premuto indipendentemente da quali altri tasti potrebbero essere tenuti premuti, devi prima filtrare tutti gli altri tasti.Questo è fatto facilmente usando Keys.Shift come un filtro:

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

Questo sarà ora vero se il tasto Shift è premuto indipendentemente da quali altre chiavi potrebbero essere premuti e false altrimenti.

3

Parte 1

E 'la logica operatore AND.

Viene utilizzato quando più flag dovrebbero essere impostabile in uno per esempio Integer:

un esempio è 3 che significa 00000011 in notazione binaria. b per esempio è 2 che significa 00000010 in notazione binaria.

Quando si desidera controllare se una ha la bandiera (il secondo bit da destra), che B rappresenta imposta si utilizza l'operatore AND:

un & b = 00000010

E quando questo è uguale a B (o è> 0) sai che il flag è impostato.

Parte 2

L'operatore uguale può essere utilizzato anche per il caso in cui si vuole verificare se "Keys.Shift" è la chiave unica "modificatore" e nessun altro è premuto. Quando si utilizza il primo codice, è possibile premere anche altri tasti "modificatori" e la condizione if rimane vera.

3

Una singola e commerciale (&) esegue un'operazione AND bit-wise; una doppia e commerciale (& &) esegue un'operazione AND booleana.

Un bit-saggio ed esegue un'operazione AND su ciascun bit di entrambi gli argomenti (quindi è chiamato "bit-saggio"). Pertanto l'output di un'operazione AND bit-saggio (o qualsiasi operazione bit-saggio) non sarà un valore booleano. Ecco alcuni esempi di bit-saggio e operazioni:

1001 & 0001 = 0001 
1101 & 1111 = 1101 

un booleano e opera su due valori booleani e restituisce un valore booleano:

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

corto circuito
un'operazione AND booleana (& &) può essere eseguito anche su due espressioni che restituiscono un valore booleano:

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

Poiché la prima espressione (a < 3) restituisce false, il risultato non può essere true perché ENTRAMBI le espressioni devono essere valutate a true in modo che il risultato sia true. Per questo motivo, la seconda espressione non verrà nemmeno valutata. Questo è chiamato "cortocircuito". Tuttavia, con un'operazione AND bit-wise, entrambe le espressioni devono essere valutate prima di eseguire l'operazione. Pertanto nella maggior parte delle situazioni in cui si desidera determinare se due elementi sono veri (booleano), il valore booleano AND (& &) sarà l'opzione migliore.

Nel tuo esempio, il codice di comparazione di singoli bit e.Modifiers con singoli bit in Keys.Shift. Nessuno dei due argomenti rappresenta un valore booleano e pertanto l'operazione è bit-wise (&) anziché booleana (& &).