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


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

Answers:


340

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

myVal = !myVal;

因此您的代码将缩短为:

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

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;
}

7
这不仅是最简单的方法,也是最干净的方法。
sharptooth

这两种情况可以在做相同事情时合并。
David Allan Finch

1
默认为:break; 真的有必要吗?没有它,开关端会不会一样?
克里斯·卢茨

12
默认值:break; 是没有必要的。
罗布K

4
如果要切换某些对象,例如object1-> system1.system2.system3.parameter1,那么使用TOGGLE(a)宏会很有帮助。这样可以防止某些错误,并使其在狭窄的屏幕上更具可读性。
OJW 2010年

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
我们可能也可以为工厂添加单例模式。
Drew

@Orm因为您是ORM?:)
mlvljr 2010年

3
请注意切换到Java的微妙建议!
机械蜗牛

好吧...我认为我们需要为此发布C ++的另一个主要版本,可能是C ++ / 51
0x6900

大家好!我认为您的方法不是可重入的。您至少需要atomic_bool,最好是互斥锁或事件队列。此外,我们需要一个观察者模式来监视val的状态。
Marco Freudenberger

38

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


1
为什么要对逻辑运算使用按位运算符?令我感到不必要的困惑。
Mark Pim

5
@Mark:对不起。猜猜我是老式的。但是,如果您的L值表达式真的很长,确实会有所帮助,因此您不必重复它。另外,您可以说flipval ^ = TRUE。那个更好吗?
Mike Dunlavey

6
@Alnitak:在某些情况下您是对的。我看到有些人将位打包在一起以“节省空间”,并且好像访问它们的指令没有占用任何空间。
Mike Dunlavey,2009年

2
@Albert:^异或运算符。0^111^10。如果忽略进位,则与添加相同。或者,您可以将其视为-如果任一位为1,则结果与另一位相反。或者,您可以将其视为一个问题:这两个位是否不同?
Mike Dunlavey

1
@MikeDunlavey,如果您使用的设备具有4M的Flash用于代码空间,而3K的SRAM用于数据空间,则这是一种行之有效的方式!
MM

33

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

x ^= true;

11
x = !x;不仅更短,而且更清晰。
罗德里戈

13
注意,例如longVariableName ^= true;,显然比短longVariableName = !longVariableName;。每个程序员都应该知道XOR。
xamid

a ^= b表示a = a ^ b,其中^表示XOR。符号a °= ba = a ° b用于任何操作员°是众多C / C ++ / C#语法很常见的。
xamid '17

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比原始代码更具可读性,更少出错和更少字符。
伏尔蒂科'17

1
此外,重复次数越少,意味着在快速的开发更改/长时间的编码/漫长的编码过程中,忘记更新等式两边的机会就越少。
Katastic Voyage

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使用?:的解决方案很接近,但是又向前迈了一步(很小)。


2
按照操作顺序,我认为您可以省略括号,以使其更简洁。:O
Drew

8

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

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

也可以。:)

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


6

高尔夫的解决方案更像是:

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;

您是否不必针对VK_F11和VK_F12检查wParam?
drby


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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.