2009-03-04 13 views
88

Po prostu chcę odwrócić wartość logiczną na podstawie tego, co już jest. Jeśli to prawda - niech to będzie fałszywe. Jeśli jest fałszywa - spraw, aby była prawdziwa.Najłatwiejszy sposób odwrócenia wartości boolowskiej?

Oto mój kod fragment:

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

Odpowiedz

285

można odwrócić wartość tak:

myVal = !myVal; 

więc Twój kod będzie skrócić do:

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

    case VK_F12: 
    otherVal = !otherVal; 
    break; 

    default: 
    break; 
} 
+4

Nie tylko jest to najłatwiejszy, ale i najczystszy sposób. – sharptooth

+4

Używam tego boolowskiego "przełączania" przez cały czas w kodzie. –

+1

succint and clear to jedyny sposób, w jaki kod – Jason

2

wolę Jana T's rozwiązanie, ale jeśli chcesz pójść cały kod-golfy, twoje zdanie logicznie sprowadza się do tego:

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

Nie musisz sprawdzać wParam przeciwko VK_F11 i VK_F12? – drby

+0

Doh! Tak, dziękuję ... Dokonałem tej edycji. – JosephStyons

4

Rozwiązanie codegolf'ish byłoby więcej takich jak:

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

Dobrze, jeśli idziemy do codegolf: flipVal = (wParam == VK_F11)! = FlipVal; ... – bobince

+0

ok, wy zyskujecie ... :) I tak nigdy nie byłem golfistą. – JosephStyons

26

Jeśli znasz wartości 0 lub 1, można zrobić flipval ^= 1.

+1

Po co używać operatora bitowego do operacji logicznej? Zapachy niepotrzebnego zaciemniania mnie. –

+4

@ Mark: Przepraszam. Chyba jestem staroświecki.Ale pomaga, jeśli wyrażenie wartości L jest naprawdę długie, więc nie trzeba go powtarzać. Możesz również powiedzieć flipval^= TRUE. Czy to jest lepsze? –

+0

@Mark - zobacz moje ogłoszenie - ponieważ czasami twoje wartości logiczne są przechowywane w bitach. Nie każdy chce zmarnować 8 bitów (lub więcej) tylko dla boolowskiej. – Alnitak

66

Oczywiście potrzebujesz wzoru fabrycznego!

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

Prawdopodobnie moglibyśmy dodać także singleton dla fabryki. – Drew

+0

@ Orm Bo jesteś _ORM_? :) – mlvljr

+2

Zauważ subtelne zalecenie, aby przejść na Javę! –

9

Tylko dla informacji - jeśli zamiast liczby całkowitej Twój pole wymagane jest pojedynczy bit w obrębie większego typu, użyj 'xor' operator Zamiast:

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

Oczywiście potrzebujesz elastycznego rozwiązania, które może obsługiwać typy maskujące się jako boolowskie. Następujące pozwala na:

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

Możesz specjalizować się dla różnych typów, które mogą udawać, że są boolean. Na przykład:

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

Przykładem wykorzystania tego konstruktu:

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

Nie, nie jestem poważny.

8

To wydaje się być całkowicie za darmo ... Heh.Oto kolejny varation, co chyba jest bardziej w kategorii „mądry” niż coś polecam dla produkcji kodu:

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

myślę, że to zalety to:

  • Bardzo lakoniczne
  • Does nie wymagają rozgałęzienia

a równie oczywistą wadę jest

  • Bardzo lakoniczne

Jest blisko rozwiązania @ Korona w użyciu? Ale podjęte jeden (mały) krok dalej.

+1

Według kolejności operacji, myślę, że można pominąć nawias dla jeszcze bardziej zwięzły. : O – Drew

6

Tylko dlatego, że mój ulubiony sposób dziwne kulki, aby włączyć bool nie ma na liście ...

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

działa zbyt. :)

(Tak x = !x; jest bardziej przejrzyste i łatwiejsze do odczytania)

19

najprostszym rozwiązaniem, które znalazłem:

x ^= true; 
+0

'x =! X;' jest nie tylko krótszy, ale również bardziej czytelny. – Rodrigo

+0

Należy zauważyć, że np. 'longVariableName^= true;' jest wyraźnie krótszy niż 'longVariableName =! longVariableName;' A każdy programista powinien znać XOR. – xamid

+0

Masz rację. Nie wiedziałem, że^= oznaczało XOR :) – Rodrigo