提问人: 提问时间:3/4/2009 最后编辑:5 revs, 4 users 96%John T 更新时间:2/24/2020 访问量:303864
翻转布尔值的最简单方法?
Easiest way to flip a boolean value?
问:
我只想根据它已经是什么来翻转布尔值。如果它是真的 - 让它成为假的。如果它是假的 - 让它成为真的。
这是我的代码摘录:
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;
}
答:
412赞
3 revs, 3 users 79%John T
#1
您可以像这样翻转值:
myVal = !myVal;
因此,您的代码将缩短为:
switch(wParam) {
case VK_F11:
flipVal = !flipVal;
break;
case VK_F12:
otherVal = !otherVal;
break;
default:
break;
}
评论
13赞
sharptooth
3/4/2009
这不仅是最简单的,也是最干净的方法。
0赞
David Allan Finch
3/4/2009
这两种情况可以合并,因为它们做同样的事情。
1赞
Chris Lutz
3/6/2009
默认值:break;真的有必要吗?没有它,开关的结局不会一样吗?
14赞
Rob K
3/6/2009
默认值:break;是不必要的。
4赞
OJW
10/1/2010
如果您要切换诸如 object1->system1.system2.system3.parameter1 之类的冗长内容,那么使用 TOGGLE(a) 宏会很有帮助。这样可以防止一些错误,并使它在窄屏幕上更具可读性。
2赞
JosephStyons
3/4/2009
#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;
评论
0赞
drby
3/4/2009
难道您不必将 wParam 与 VK_F11 和 VK_F12 进行对比吗?
9赞
korona
3/5/2009
#3
codegolf'ish 解决方案更像是:
flipVal = (wParam == VK_F11) ? !flipVal : flipVal;
otherVal = (wParam == VK_F12) ? !otherVal : otherVal;
46赞
Mike Dunlavey
3/5/2009
#4
如果您知道值为 0 或 1,则可以执行 .flipval ^= 1
评论
1赞
Mark Pim
3/5/2009
为什么要使用按位运算符进行逻辑运算?对我来说,闻起来有不必要的混淆。
6赞
Mike Dunlavey
3/5/2009
@Mark:对不起。猜猜我是老式的。但是,如果您的 L 值表达式真的很长,它确实会有所帮助,因此您不必重复它。另外,你可以说flipval ^= TRUE。这样会更好吗?
6赞
Mike Dunlavey
3/6/2009
@Alnitak:在某些情况下,你是对的。我见过一些人为了“节省空间”而将位打包在一起,并表现得好像访问它们的指令不占用任何空间。
2赞
Mike Dunlavey
11/12/2013
@Albert:是排他性或运算符。 是 ,并且是 。这与忽略进位时添加相同。或者你可以把它想象成 - 如果任一位是 1,则结果是另一位的倒数。或者你可以把它想象成问一个问题:这两个位不同吗?^
0^1
1
1^1
0
1赞
M.M
12/16/2014
@MikeDunlavey,如果您使用的设备具有 4M 闪存作为代码空间,3K SRAM 用于数据空间,那么这是一种合理的行为方式!
98赞
Drew
3/5/2009
#5
显然,你需要一个工厂模式!
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>
评论
16赞
Drew
3/5/2009
我们可能也可以为工厂添加单例模式。
1赞
mlvljr
3/20/2010
@Orm 因为你是ORM?:)
7赞
Mechanical snail
12/20/2012
请注意切换到 Java 的微妙建议!
1赞
0x6900
9/15/2015
井。。。我认为我们需要另一个主要的C++版本,可能是C++/51
3赞
Casey
5/4/2020
我不确定这是惊人的还是可怕的......可能很神奇。给初学者的提示:事实上,德鲁是在讽刺。您应该选择尽可能简单(但不更简单)的解决方案......虽然工厂模式很强大,你应该学习它。</不是讽刺>
17赞
Alnitak
3/5/2009
#6
仅供参考 - 如果必填字段不是整数,而是较大类型中的单个位,请改用“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;
1赞
dma
3/5/2009
#7
显然,您需要一个灵活的解决方案,该解决方案可以支持伪装成布尔值的类型。以下允许这样做:
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"); }
不,我不是认真的。
10赞
unwind
3/5/2009
#8
这似乎是一个免费的......嘿。这是另一个变体,我想它更像是“聪明”的类别,而不是我推荐用于生产代码的东西:
flipVal ^= (wParam == VK_F11);
otherVal ^= (wParam == VK_F12);
我想它的优点是:
- 非常简洁
- 不需要分支
一个同样明显的缺点是
- 非常简洁
这接近于@korona使用 ?: 的解决方案,但又向前迈进了一小步。
评论
3赞
Drew
9/29/2011
按照操作顺序,我认为您可以省略括号以使其更简洁。:O
12赞
Rozwel
#9
仅仅因为我最喜欢的奇怪的球切换布尔值的方式没有列出......
bool x = true;
x = x == false;
也有效。:)
(是的,更清晰,更易于阅读)x = !x;
3赞
evandrix
#10
flipVal ^= 1;
同样如此
otherVal
55赞
xamid
#11
我发现的最简单的解决方案:
x ^= true;
评论
29赞
Rodrigo
10/4/2017
x = !x;
不仅更短,而且更清晰。
32赞
xamid
10/6/2017
请注意,例如 显然比 每个程序员都应该知道 XOR。longVariableName ^= true;
longVariableName = !longVariableName;
8赞
Vortico
10/31/2017
轶事,但我最近遇到了这条线 当然,最干净的做法是将其扩展到多行并使用临时变量来存储对象,但与原始代码相比,可读性更强,更不容易出错,字符更少。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
3赞
Katastic Voyage
11/14/2017
此外,更少的重复意味着在快速开发更改/漫长的日/夜编码期间忘记更新等式两边的机会更少。
1赞
migle
4/30/2020
@Vortico,轶事,但正是为了避免这样的台词,我今天来到这里。我想你可以说冗长也有混淆。
0赞
Artur
#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;
}
0赞
Jon
#13
只是因为我喜欢质疑代码。我建议你也可以通过做这样的事情来利用三元:
例:
bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;
评论