Bir boole değerini çevirmenin en kolay yolu?


124

Ben sadece bir boolean zaten ne olduğuna göre çevirmek istiyorum. Doğruysa - yanlış yapın. Yanlışsa - doğru yapın.

İşte kod pasajım:

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

Yanıtlar:


341

Bir değeri şöyle çevirebilirsiniz:

myVal = !myVal;

böylece kodunuz şu şekilde kısaltılır:

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

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;
}

7
Sadece bu en kolay değil, aynı zamanda en temiz yoldur.
keskin dişli

iki durum aynı şeyi yaptıkları için birleştirilebilir.
David Allan Finch 04

1
Öntanımlıdır: break; gerçekten gerekli mi? Anahtar onsuz aynı şekilde bitmeyecek mi?
Chris Lutz

12
Varsayılan: break; gereksizdir.
Rob K

4
Object1-> system1.system2.system3.parameter1 gibi uzun soluklu bir şeyi değiştiriyorsanız, bir TOGGLE (a) makrosuna sahip olmak faydalı olabilir. Bu, bazı hataları önler ve hepsini dar ekranlarda daha okunabilir hale getirir.
OJW

77

Açıkça bir fabrika modeline ihtiyacınız var!

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>

9
Muhtemelen fabrika için de tekli desen ekleyebiliriz.
Drew

@Orm ORM olduğunuz için mi? :)
mlvljr

3
Java'ya geçme konusundaki ince önerilere dikkat edin!
Mekanik salyangoz

Pekala ... Bunun için başka bir büyük C ++ sürümüne ihtiyacımız olduğunu düşünüyorum, C ++ / 51
0x6900

Hey Millet! Bence yaklaşımınız evresel değil. En azından atomic_bool'a ihtiyacınız var, daha iyi bir muteks veya bir olay kuyruğu. Ayrıca, val durumunu izlemek için bir gözlemci modeline ihtiyacımız var.
Marco Freudenberger

38

Değerlerin 0 veya 1 olduğunu biliyorsanız, yapabilirsiniz flipval ^= 1.


1
Mantıksal bir işlem için neden bitsel operatör kullanılıyor? Gereksiz şaşkınlık kokuyor bana.
Mark Pim 04

5
@Mark: Üzgünüm. Sanırım ben eski kafalıyım. Ancak L değeri ifadenizin gerçekten uzun olması yardımcı olur, bu yüzden onu tekrarlamanız gerekmez. Ayrıca, flipval ^ = DOĞRU diyebilirsiniz. Bu daha iyi mi?
Mike Dunlavey 04

6
@Alnitak: Bazı durumlarda haklısın. Bazı insanların "yer kazanmak" için parçaları bir araya topladıklarını ve bunlara erişim talimatları hiç yer kaplamamış gibi davrandıklarını gördüm.
Mike Dunlavey

2
@Albert: ^olduğu dışlamalı veya operatörü. 0^1olduğu 1ve 1^1bir 0. Taşıma bitini görmezden gelirseniz eklemekle aynı şeydir. Ya da - eğer bitlerden biri 1 ise, sonuç diğer bitin tersidir. Ya da şu soruyu sorduğunuzu düşünebilirsiniz: Bu iki bit farklı mı?
Mike Dunlavey

1
@MikeDunlavey, kod alanı için 4M Flash ve veri alanı için 3K SRAM olan bir cihazdaysanız, o zaman bu haklı bir hareket şeklidir!
MM

33

Bulduğum en kolay çözüm:

x ^= true;

11
x = !x;sadece daha kısa değil, aynı zamanda daha okunaklı.
Rodrigo

13
Örneğin longVariableName ^= true;, açıkça daha kısa olduğunu longVariableName = !longVariableName;ve her programcının XOR'u bilmesi gerektiğini unutmayın.
xamid

a ^= banlamı a = a ^ b, ^XOR anlamına gelir. Herhangi bir işleç için gösterim a °= b, C / C ++ / C # sözdizimi arasında çok yaygındır. a = a ° b°
xamid

2
Anekdot, ancak kısa süre önce satırla karşılaştım gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value = !gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value;Tabii ki, yapılacak en temiz şey, onu birden çok satıra genişletmek ve nesneleri depolamak için geçici değişkenler kullanmaktır, ancak gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value ^= 1çok daha okunabilir, daha az hataya açık ve orijinal koddan daha az karakter .
Vortico

1
Ek olarak, daha az çoğaltma, hızlı geliştirme değişiklikleri / uzun günler / geceler kodlama sırasında denklemin HER İKİ tarafını da güncellemeyi unutmak için daha az şans demektir.
Katastic Voyage

11

Sadece bilgi için - eğer bir tamsayı yerine gerekli alanınız daha büyük bir tür içinde tek bir bit ise, bunun yerine 'xor' operatörünü kullanın:

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 & flag_b) != 0;

9

Bu herkes için ücretsiz gibi görünüyor ... Heh. İşte başka bir varyasyon, sanırım "akıllı" kategorisinde üretim kodu için önerdiğim bir şeyden daha fazlası:

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

Sanırım avantajları:

  • Çok kısa
  • Dallanma gerektirmez

Ve aynı derecede bariz bir dezavantaj,

  • Çok kısa

Bu, @ korona'nın?: Kullanan çözümüne yakındır, ancak bir (küçük) adım daha ileri götürülür.


2
İşlem sırasına göre, daha da özlü için parantezi atlayabileceğinizi düşünüyorum. : O
Drew

8

Sırf bir sopayı değiştirmenin en sevdiğim garip top yolu listelenmemiş diye ...

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

çok çalışıyor. :)

(evet x = !x;daha net ve okunması daha kolay)


6

Kod golfçü çözümü daha çok şuna benzer:

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

2

John T'nin çözümünü tercih ederim, ancak tamamen kodlama yapmak istiyorsanız, ifadeniz mantıksal olarak buna indirgenir:

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

WParam'ı VK_F11 ve VK_F12 ile karşılaştırmak zorunda değil misiniz?
drby


0

Açıkçası, boolean olarak maskelenen türleri destekleyebilecek esnek bir çözüme ihtiyacınız var. Aşağıdakiler buna izin verir:

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

Daha sonra bunu, booleanmış gibi görünebilecek farklı türler için özelleştirebilirsiniz. Örneğin:

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

Bu yapıyı kullanmanın bir örneği:

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

Hayır, ciddi değilim.


0

0 ve 1 değerlerine sahip tamsayılar için şunları deneyebilirsiniz:

value = abs(value - 1);

C'de MWE:

#include <stdio.h>
#include <stdlib.h>
int main()
{
        printf("Hello, World!\n");
        int value = 0;
        int i;
        for (i=0; i<10; i++)
        {
                value = abs(value -1);
                printf("%d\n", value);
        }
        return 0;
}

0

Sadece kodu sorgulamayı sevdiğim için. Bunun gibi bir şey yaparak üçlüden de yararlanabileceğinizi öneriyorum:

Misal:

bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.