翻转布尔值的最简单方法是什么?

Joh*_*n T 113 c c++ boolean-logic boolean

我只是想根据它已经是什么来翻转一个布尔值.如果这是真的 - 把它弄错.如果它是假的 - 让它成真.

这是我的代码摘录:

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;
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*n T 325

您可以像这样翻转一个值:

myVal = !myVal;
Run Code Online (Sandbox Code Playgroud)

所以你的代码会缩短为:

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

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;
}
Run Code Online (Sandbox Code Playgroud)

  • 默认值:break; 没必要. (10认同)
  • 这不仅是最简单的,也是最干净的方式. (5认同)
  • 我一直在代码中使用这个布尔"切换". (4认同)
  • 如果你正在切换像object1-> system1.system2.system3.parameter1那样冗长的东西,那么拥有一个TOGGLE(a)宏会很有帮助.这可以防止出现一些错误,并使其在狭窄的屏幕上更具可读性. (3认同)

Dre*_*rew 74

显然你需要一个工厂模式!

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!");
   }
}
Run Code Online (Sandbox Code Playgroud)

:d

</sarcasm>
Run Code Online (Sandbox Code Playgroud)

  • 我们也可以为工厂添加单例模式. (7认同)
  • 我不确定这是否令人惊奇或可怕......可能令人惊奇。给初学者的提示:德鲁实际上是在讽刺。您应该寻求尽可能简单(但不能更简单)的解决方案......尽管工厂模式非常强大,您应该学习它。&lt;/不是讽刺&gt; (4认同)
  • 请注意切换到Java的微妙建议! (2认同)
  • 大声笑......我们还需要一个切换布尔静态库 (2认同)

Mik*_*vey 33

如果您知道值为0或1,则可以这样做flipval ^= 1.

  • @Alnitak:在某些情况下你是对的.我看到有些人把位打包在一起"节省空间",就像访问它们的指令没有占用任何空间一样. (6认同)
  • @Mark:对不起.猜猜我是老式的.但是如果你的L值表达式真的很长,它确实有帮助,所以你不必重复它.另外,你可以说flipval ^ = TRUE.那个更好吗? (5认同)
  • @Albert:`^`是_exclusive-or_运算符.`0 ^ 1`是'1`,'1 ^ 1`是'0`.如果忽略进位,则与添加相同.或者您可以将其视为 - 如果任一位为1,则结果是另一位的倒数.或者您可以将其视为提出问题:这两个位是否有所不同? (2认同)

xam*_*mid 27

我找到的最简单的解决方案:

x ^= true;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,例如`longVariableName ^ = true;`明显比`longVariableName =!longVariableName;`并且每个程序员都应该知道XOR. (8认同)
  • `x =!x;`不仅更短,而且更清晰. (6认同)
  • 轶事,但我最近遇到了`gRackWidget-&gt;modules-&gt;first().lights[PATTERN1_LIGHT + i].value = !gRackWidget-&gt;modules-&gt;first().lights[PATTERN1_LIGHT + i].value;`当然,最干净的做法是将其扩展为多行并使用临时变量来存储对象,但是`gRackWidget-&gt;modules-&gt;first().lights[PATTERN1_LIGHT + i].value ^= 1` 就太多了与原始代码相比,可读性更强,错误更少,字符更少。 (4认同)
  • 此外,更少的重复意味着在快速的开发变化/长时间的编码过程中忘记更新等式两边的机会更少。 (3认同)

Aln*_*tak 10

仅供参考 - 如果不是整数,则所需字段是较大类型中的单个位,请使用'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;
Run Code Online (Sandbox Code Playgroud)


unw*_*ind 9

这似乎是一个免费的...嘿.这是另一个变体,我想这更像是"聪明"的类别而不是我为生产代码推荐的东西:

flipVal ^= (wParam == VK_F11);
otherVal ^= (wParam == VK_F12);
Run Code Online (Sandbox Code Playgroud)

我猜它的优点是:

  • 非常简洁
  • 不需要分支

一个明显的缺点是

  • 非常简洁

这接近使用?的@ korona解决方案:但是进一步采取了一个(小)步骤.

  • 按操作顺序,我认为你可以省略括号,更简洁.:o (2认同)

Roz*_*wel 8

只是因为我最喜欢的奇怪的球方式切换bool没有列出...

bool x = true;
x = x == false;
Run Code Online (Sandbox Code Playgroud)

也有效.:)

(是的x = !x;,更清晰,更容易阅读)


kor*_*ona 6

codegolf'ish解决方案更像是:

flipVal = (wParam == VK_F11) ? !flipVal : flipVal;
otherVal = (wParam == VK_F12) ? !otherVal : otherVal;
Run Code Online (Sandbox Code Playgroud)

  • 好吧,如果我们要去codegolf:flipVal =(wParam == VK_F11)!= flipVal; ... (6认同)