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

Posted

技术标签:

【中文标题】翻转布尔值的最简单方法?【英文标题】:Easiest way to flip a boolean value? 【发布时间】:2010-10-11 06:54:39 【问题描述】:

我只想根据它已经是什么来翻转一个布尔值。如果它是真的 - 让它成为假的。如果它是假的 - 让它成为真的。

这是我的代码摘录:

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;

【问题讨论】:

【参考方案1】:

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

myVal = !myVal;

因此您的代码将缩短为:

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

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;

【讨论】:

这不仅是最简单的,也是最干净的方式。 这两种情况可以合并,因为它们做同样的事情。 默认:break;真的有必要吗?没有它,开关不会结束吗? 默认值:break;是不必要的。 如果您要切换像 object1->system1.system2.system3.parameter1 这样冗长的东西,那么使用 TOGGLE(a) 宏会很有帮助。这可以防止一些错误,并使其在窄屏幕上更具可读性。【参考方案2】:

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

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>

【讨论】:

我们也可以为工厂添加单例模式。 @Orm 因为你是一个ORM? :) 注意转换到 Java 的微妙建议! 嗯...我认为我们需要另一个主要版本的 C++ 来解决这个问题,可能是 C++/51 我不确定这是惊人的还是可怕的......可能很棒。给初学者的提示:事实上,德鲁是在讽刺。你应该寻求一个尽可能简单(但不是更简单)的解决方案......虽然工厂模式非常强大,你应该学习它。 不是讽刺>【参考方案3】:

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

x ^= true;

【讨论】:

x = !x; 不仅更短,而且更清晰。 请注意,例如longVariableName ^= true; 明显比 longVariableName = !longVariableName; 短而且每个程序员都应该知道 XOR。 传闻,不过最近碰到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就多了比原始代码更易读、更不容易出错、字符更少。 此外,更少的重复意味着在快速的开发变化/漫长的日日夜夜的编码过程中忘记更新等式两边的机会更少。 @Vortico,轶事,但正是为了避免这样的行,我今天来到这里。我想你可以说冗长也有混淆。【参考方案4】:

如果您知道值是 0 或 1,则可以使用 flipval ^= 1

【讨论】:

为什么使用位运算符进行逻辑运算?我闻到了不必要的混淆。 @Mark:对不起。估计我老了但是,如果您的 L 值表达式真的很长,它确实会有所帮助,因此您不必重复它。此外,您可以说 Flipval ^= TRUE。这样更好吗? @Alnitak:在某些情况下你是对的。我见过一些人把一些东西打包在一起以“节省空间”,并表现得好像访问它们的指令没有占用任何空间。 @Albert: ^exclusive-or 运算符。 0^111^10。如果忽略进位位,则与添加相同。或者您可以将其视为 - 如果任一位为 1,则结果是另一位的倒数。或者你可以把它想象成问一个问题:这两点有什么不同吗? @MikeDunlavey 如果您使用的是具有 4M 闪存用于代码空间,3K SRAM 用于数据空间的设备,那么这是一种合理的行为方式!【参考方案5】:

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

【讨论】:

【参考方案6】:

这似乎是一个免费的...呵呵。这是另一种变体,我想它比我推荐的生产代码更属于“聪明”类别:

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

我猜它的优点是:

非常简洁 不需要分支

同样明显的缺点是

非常简洁

这与@korona 使用 ?: 的解决方案很接近,但更进一步。

【讨论】:

按操作顺序,我认为您可以省略括号以更简洁。 :O【参考方案7】:

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

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

也可以。 :)

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

【讨论】:

【参考方案8】:

codegolf 的解决方案更像是:

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

【讨论】:

【参考方案9】:
flipVal ^= 1;

同样适用

otherVal

【讨论】:

【参考方案10】:

我更喜欢 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 吗?【参考方案11】:

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

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

不,我不是认真的。

【讨论】:

【参考方案12】:

对于值为 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;

【讨论】:

【参考方案13】:

只是因为我喜欢质疑代码。我建议您也可以通过执行以下操作来使用三元:

例子:

bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;

【讨论】:

以上是关于翻转布尔值的最简单方法?的主要内容,如果未能解决你的问题,请参考以下文章

在视图中访问 Phalcon 配置值的最简单方法是啥?

在单CPU指令中可以在0和1之间翻转位/整数/布尔值的任何可能代码

设置整个数组的值的最简单方法是啥?

从 HtmlHelper 的扩展方法中传递的 lambda 表达式中获取属性值的最简单方法是啥?

在 2D 矢量中的预定位置更改多个值的最简单方法是啥?

访问html表单JavaScript中文本输入字段值的最简单方法?