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

问题描述 投票:0回答:14

我只想根据已有的布尔值来翻转它。如果它是真的——就让它变成假的。如果它是假的 - 让它变成真的。

这是我的代码摘录:

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;
}
c++ c boolean boolean-logic
14个回答
414
投票

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

myVal = !myVal;

因此您的代码将缩短为:

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

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;
}

98
投票

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

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>

56
投票

我发现的最简单的解决方案:

x ^= true;

46
投票

如果您知道这些值为 0 或 1,您可以这样做

flipval ^= 1


17
投票

仅供参考 - 如果您所需的字段不是整数,而是较大类型中的单个位,请改用“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;

12
投票

只是因为我最喜欢的奇怪的切换布尔值的方法没有列出......

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

也有效。 :)

(是的,

x = !x;
更清晰易读)


10
投票

这好像是一场混战……呵呵。这是另一个变体,我想它更属于“聪明”类别,而不是我推荐的生产代码:

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

我想它的优点是:

  • 非常简洁
  • 不需要分支

同样明显的缺点是

  • 非常简洁

这接近@korona 使用 ?: 的解决方案,但又向前迈出了一小步。


9
投票

codegolf'ish 的解决方案更像是:

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

3
投票
flipVal ^= 1;

同样适用于

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;

1
投票

显然您需要一个灵活的解决方案来支持伪装成布尔值的类型。以下允许这样做:

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;

0
投票

如果不引发 clang-tidy 的同义反复比较错误,我就无法让 boolean != boolean 或其任何变体工作。我的解决方案不是禁用警告(如果您要忽略警告,为什么要启用警告!),我的解决方案是在函数内添加一个小 lambda:

auto flip_boolean{ [](bool item) {
  if (item == true) { return false; }
  return true;
} };

这不仅否定了警告,而且我认为还提高了可读性,因为 Flip_boolean 明确地表达了所需的行为。编译器最终可能会优化它,所以没有必要在输入上节俭。

© www.soinside.com 2019 - 2024. All rights reserved.