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.