2009-03-04 23 views
88

Voglio solo capovolgere un booleano basato su quello che è già. Se è vero, rendilo falso. Se è falso, rendilo vero.Il modo più semplice per capovolgere un valore booleano?

Ecco il mio codice estratto:

switch(wParam) { 

case VK_F11: 
    if (flipVal == true) { 
    flipVal = false; 
    } else { 
    flipVal = true; 
    } 
break; 

case VK_F12: 
    if (otherVal == true) { 
    otherValVal = false; 
    } else { 
    otherVal = true; 
    } 
break; 

default: 
break; 
} 

risposta

285

è possibile capovolgere un valore in questo modo:

myVal = !myVal; 

modo che il codice sarebbe abbreviare verso il basso per:

switch(wParam) { 
    case VK_F11: 
    flipVal = !flipVal; 
    break; 

    case VK_F12: 
    otherVal = !otherVal; 
    break; 

    default: 
    break; 
} 
+4

Non solo questo è il modo più semplice, ma anche il più pulito. – sharptooth

+4

Io uso questo "toggle" booleano per tutto il tempo nel codice. –

+1

succint e clear è l'unico codice di modo – Jason

2

preferisco John La soluzione di T, ma se vuoi fare tutto il codice-golfy, la tua affermazione si riduce logicamente a questo:

//if key is down, toggle the boolean, else leave it alone. 
flipVal = ((wParam==VK_F11) && !flipVal) || (!(wParam==VK_F11) && flipVal); 
if(wParam==VK_F11) Break; 

//if key is down, toggle the boolean, else leave it alone. 
otherVal = ((wParam==VK_F12) && !otherVal) || (!(wParam==VK_F12) && otherVal); 
if(wParam==VK_F12) Break; 
+0

Non devi controllare wParam contro VK_F11 e VK_F12? – drby

+0

Doh! Sì, grazie ... Ho fatto quella modifica. – JosephStyons

4

La soluzione codegolf'ish sarebbe più simile:

flipVal = (wParam == VK_F11) ? !flipVal : flipVal; 
otherVal = (wParam == VK_F12) ? !otherVal : otherVal; 
+5

Beh, se stiamo andando a codegolf: flipVal = (wParam == VK_F11)! = FlipVal; ... – bobince

+0

ok, voi ragazzi vincete ... :) Non sono mai stato un grande golfista. – JosephStyons

26

Se si conoscono i valori sono 0 o 1, si potrebbe fare flipval ^= 1.

+1

Perché utilizzare un operatore bit a bit per un'operazione logica? Odori di inutile offuscamento per me. –

+4

@ Mark: scusa. Credo di essere vecchio stile.Ma aiuta se l'espressione del valore L è molto lunga, quindi non devi ripeterla. Inoltre, potresti dire flipval^= TRUE. È meglio? –

+0

@Mark - guarda il mio post - perché a volte i tuoi valori logici sono memorizzati in bit. Non tutti vogliono sprecare un intero 8 bit (o più) solo per un booleano. – Alnitak

66

Chiaramente avete bisogno di un modello di fabbrica!

KeyFactory keyFactory = new KeyFactory(); 
KeyObj keyObj = keyFactory.getKeyObj(wParam); 
keyObj.doStuff(); 


class VK_F11 extends KeyObj { 
    boolean val; 
    public void doStuff() { 
     val = !val; 
    } 
} 

class VK_F12 extends KeyObj { 
    boolean val; 
    public void doStuff() { 
     val = !val; 
    } 
} 

class KeyFactory { 
    public KeyObj getKeyObj(int param) { 
     switch(param) { 
     case VK_F11: 
      return new VK_F11(); 
     case VK_F12: 
      return new VK_F12(); 
     } 
     throw new KeyNotFoundException("Key " + param + " was not found!"); 
    } 
} 

: D

</sarcasm> 
+5

Probabilmente potremmo aggiungere anche il modello singleton per la fabbrica. – Drew

+0

@Orm Perché sei un _ORM_? :) – mlvljr

+2

Nota la raccomandazione sottile di passare a Java! –

9

Solo per informazione - se invece di un intero vostro campo obbligatorio è un singolo bit all'interno di un tipo più grande, utilizzare l'operatore 'xor' invece:

int flags; 

int flag_a = 0x01; 
int flag_b = 0x02; 
int flag_c = 0x04; 

/* I want to flip 'flag_b' without touching 'flag_a' or 'flag_c' */ 
flags ^= flag_b; 

/* I want to set 'flag_b' */ 
flags |= flag_b; 

/* I want to clear (or 'reset') 'flag_b' */ 
flags &= ~flag_b; 

/* I want to test 'flag_b' */ 
bool b_is_set = (flags & flab_b) != 0; 
0

Chiaramente hai bisogno di una soluzione flessibile in grado di supportare tipi mascherati come booleani. Quello che segue lo consente:

template<typename T> bool Flip(const T& t); 

È quindi possibile specializzarlo per diversi tipi che potrebbero fingere di essere booleani. Per esempio:

template<> bool Flip<bool>(const bool& b) { return !b; } 
template<> bool Flip<int>(const int& i) { return !(i == 0); } 

Un esempio di utilizzo di questo costrutto:

if(Flip(false)) { printf("flipped false\n"); } 
if(!Flip(true)) { printf("flipped true\n"); } 

if(Flip(0)) { printf("flipped 0\n"); } 
if(!Flip(1)) { printf("flipped 1\n"); } 

No, io non sono gravi.

8

Questo sembra essere un free-for-all ... Heh.Ecco un altro varation, che credo sia più nella categoria "intelligente" che qualcosa mi consiglia per il codice di produzione:

flipVal ^= (wParam == VK_F11); 
otherVal ^= (wParam == VK_F12); 

Credo che sia vantaggi sono:

  • molto conciso
  • fa non richiede ramificazione

e uno svantaggio altrettanto evidente è

  • molto conciso

Questo è vicino alla soluzione @ di Korona utilizzando:? Ma preso un (piccolo) passo avanti.

+1

Per ordine di operazioni, penso che si possa omettere la parentesi per ancor più concisa. : O – Drew

6

Solo perché il mio modo preferito palla strano per attivare o disattivare un bool non è elencato ...

bool x = true; 
x = x == false; 

funziona troppo. :)

(sì il x = !x; è più chiara e più facile da leggere)

1
flipVal ^= 1; 

stesso vale per

otherVal 
19

soluzione più semplice che ho trovato:

x ^= true; 
+0

'x =! X;' non è solo più breve, ma anche più leggibile. – Rodrigo

+0

Nota che ad es. 'longVariableName^= true;' è chiaramente più corto di 'longVariableName =! longVariableName;' E ogni programmatore dovrebbe conoscere XOR. – xamid

+0

Hai ragione. Non sapevo che^= intendesse XOR :) – Rodrigo

Problemi correlati