ブール値をフリップする最も簡単な方法は?


124

私はそれが既に何であるかに基づいてブールを反転したいだけです。それが真の場合-偽にします。それが偽の場合-それを真にします。

これが私のコードの抜粋です:

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

回答:


340

次のように値を反転できます:

myVal = !myVal;

したがって、コードは次のように短くなります。

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

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;
}

7
これは最も簡単なだけでなく、最もクリーンな方法でもあります。
シャープトゥース2009年

2つのケースは同じことを行うため、マージできます。
デビッドアランフィンチ

1
デフォルトは次のとおりです。本当に必要ですか?スイッチはそれなしでも同じように終わりませんか?
Chris Lutz、

12
デフォルト:break; 不要です。
Rob K

4
object1-> system1.system2.system3.parameter1のように長々としたものを切り替える場合は、TOGGLE(a)マクロを使用すると便利です。これにより、いくつかのミスを防ぎ、狭い画面でも読みやすくなります。
OJW

77

明らかにファクトリーパターンが必要です!

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
おそらく、ファクトリーのシングルトンパターンを追加することもできます。
ドリュー

@OrmあなたはORMなの?:)
mlvljr 2010年

3
Javaに切り替えるための微妙な推奨事項に注意してください!
メカニカルカタツムリ

まあ...私はこれのためにC ++の別のメジャーリリースが必要だと思います、C ++ / 51かもしれません
0x6900

やあみんな!あなたのアプローチは再入可能ではないと思います。少なくともatomic_boolが必要です。ミューテックスまたはイベントキューの方が優れています。さらに、valの状態を監視するためのオブザーバーパターンが必要です。
Marco Freudenberger

38

値が0または1であることがわかっている場合は、実行できますflipval ^= 1


1
論理演算にビット演算子を使用する理由 私にとって不必要な難読化の匂い。
マーク・ピム

5
@マーク:申し訳ありません。私は時代遅れだと思います。ただし、L値の式が本当に長い場合は、繰り返し使用する必要がないので役立ちます。また、flipval ^ = TRUEと言うこともできます。それは良いですか?
Mike Dunlavey、2009年

6
@Alnitak:状況によっては正しいです。「スペースを節約する」ためにビットをまとめて、それらにアクセスするための命令がスペースを取らないかのように行動する人々を見たことがあります。
Mike Dunlavey、2009年

2
@Albert:^ある排他的論理和演算子。0^1であり11^1です0。キャリービットを無視した場合の追加と同じです。または、それを次のように考えることもできます-いずれかのビットが1の場合、結果は他のビットの逆になります。または、質問をすることと考えることができます:これらの2つのビットは異なりますか?
Mike Dunlavey 2013年

1
@MikeDunlaveyで、コードスペース用に4Mのフラッシュ、データスペース用に3KのSRAMを搭載したデバイスを使用している場合、これは正当な方法です。
MM

33

私が見つけた最も簡単な解決策:

x ^= true;

11
x = !x;が短くなるだけでなく、読みやすくなります。
ロドリゴ

13
例えばlongVariableName ^= true;、明らかにlongVariableName = !longVariableName;すべてのプログラマがXORを知っている必要があります。
xamid 2017年

a ^= bはを意味しa = a ^ b、ここ^でXORを意味します。演算子の表記法a °= ba = a ° b°C / C ++ / C#構文の間で非常に一般的です。
xamid 2017年

2
逸話的ですが、最近この行に出くわしましたgRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value = !gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value;もちろん、最もクリーンなことは、それを複数行に展開し、一時変数を使用してオブジェクトを格納することですがgRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value ^= 1、元のコードよりもはるかに読みやすく、エラーが発生しにくく、文字数も少なくなります。
Vortico 2017年

1
さらに、重複が少ないということは、急速な開発変更/長い日/夜のコーディング中に方程式の両側を更新し忘れる可能性が少ないことを意味します。
Katastic Voyage 2017

11

参考までに-整数ではなく、必要なフィールドがより大きな型内の単一ビットである場合は、代わりに「xor」演算子を使用します。

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

これは誰にとっても無料のようです...へえ。これが別のバリエーションです。これは、量産コードに推奨するものよりも「賢い」カテゴリにあると思います。

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

それの利点は次のとおりです:

  • とても簡潔
  • 分岐は必要ありません

同様に明らかな欠点は

  • とても簡潔

これは、@:を使用した@koronaのソリューションに近いですが、さらに1つ(小さな)ステップを踏みました。


2
操作の順序で、括弧を省略してさらに簡潔にすることができると思います。:O
ドリュー

8

ブールを切り替える私のお気に入りの奇妙なボールの方法がリストされていないからといって...

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

も動作します。:)

(はい、x = !x;より明確で読みやすいです)


6

codegolf'ishソリューションは次のようになります。

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

2

私はJohn Tの解決策を好みますが、すべてのコードに行きたくなったら、論理的には次のようになります。

//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およびVK_F12に対してチェックする必要はありませんか?
drby 2009年


0

明らかに、ブール値を装った型をサポートできる柔軟なソリューションが必要です。以下はそれを可能にします:

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

次に、これを、ブール値のふりをするさまざまなタイプに特化できます。例えば:

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

この構成の使用例:

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

いいえ、本気ではありません。


0

値が0と1の整数の場合、次のことを試すことができます。

value = abs(value - 1);

Cの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

コードに質問したいからです。私はあなたがこのようなことをすることによって三項を利用することもできると提案します:

例:

bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.