2009-03-04 11 views
88

Solo quiero voltear un booleano basado en lo que ya es. Si es verdad, hazlo falso. Si es falso, hazlo cierto.¿La forma más fácil de voltear un valor booleano?

Aquí está mi código extracto:

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; 
} 

Respuesta

285

se puede voltear un valor de este modo:

myVal = !myVal; 

lo que el código podría acortar hasta:

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

    case VK_F12: 
    otherVal = !otherVal; 
    break; 

    default: 
    break; 
} 
+4

No sólo esto es la manera más fácil, pero también la más limpia. – sharptooth

+4

Utilizo este "alternar" booleano todo el tiempo en el código. –

+1

succint y clear es la única manera código – Jason

2

prefiero John La solución de T, pero si quieres usar code-golfy, tu afirmación se reduce lógicamente a esto:

//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

¿No tienes que comprobar wParam contra VK_F11 y VK_F12? – drby

+0

Doh! Sí, gracias ... He hecho esa edición. – JosephStyons

4

La solución codegolf'ish sería más como:

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

Bueno, si vamos a codegolf: flipVal = (wParam == VK_F11)! = FlipVal; ... – bobince

+0

bien, ustedes ganan ... :) De todos modos, nunca fui gran golfista. – JosephStyons

26

Si conoce los valores son 0 ó 1, se puede hacer flipval ^= 1.

+1

¿Por qué utilizar un operador bit a bit para una operación lógica? Huele a ofuscación innecesaria para mí. –

+4

@Mark: Lo siento. Supongo que estoy pasado de moda.Pero ayuda si su expresión de valor L es realmente larga, por lo que no tiene que repetirla. Además, podría decir flipval^= TRUE. ¿Eso está mejor? –

+0

@Mark - vea mi publicación - porque a veces sus valores lógicos se almacenan en bits. No todos quieren desperdiciar 8 bits enteros (o más) solo para un booleano. – Alnitak

66

¡Claramente necesita un patrón de fábrica!

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

Probablemente podríamos agregar en el patrón de singleton para la fábrica también. – Drew

+0

@Orm ¿Porque eres un _ORM_? :) – mlvljr

+2

¡Observe la sutil recomendación de cambiar a Java! –

9

Sólo para información - si en vez de un entero su campo obligatorio es un solo bit dentro de un tipo más grande, utilice el operador XOR 'en su lugar:

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

Claramente necesita una solución flexible que pueda admitir tipos enmascarados como booleanos. Lo siguiente permite eso:

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

A continuación, puede especializar esto para diferentes tipos que pueden pretender ser booleanos. Por ejemplo:

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

Un ejemplo del uso de esta construcción:

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, no lo digo en serio.

8

Esto parece ser un para-todo ... Heh.Aquí hay otro varation, que supongo que es más en la categoría "inteligente" que algo que recomiendo para el código de producción:

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

supongo que es ventajas son:

  • muy concisa
  • ¿El no requiere de ramificación

y una desventaja obvia es tan

  • muy concisa

Esto se acerca a la solución de @ Korona usando:? Pero toma una (pequeña) paso más allá.

+1

Por orden de operaciones, creo que puede omitir el paréntesis para aún más escueto. : O – Drew

6

El hecho de que mi forma favorita bola impar para alternar un bool no aparece ...

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

también funciona. :)

(sí el x = !x; es más clara y fácil de leer)

1
flipVal ^= 1; 

mismo ocurre con

otherVal 
19

solución más fácil que he encontrado:

x ^= true; 
+0

'x =! X;' no solo es más corto, sino que también es más legible. – Rodrigo

+0

Tenga en cuenta que, por ejemplo, 'longVariableName^= true;' es claramente más corto que 'longVariableName =! longVariableName;' Y cada programador debe conocer XOR. – xamid

+0

Tienes razón. No sabía que^= significaba XOR :) – Rodrigo

Cuestiones relacionadas