我只想根据已有的布尔值来翻转它。如果它是真的——就让它变成假的。如果它是假的 - 让它变成真的。
这是我的代码摘录:
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;
}
您可以像这样翻转一个值:
myVal = !myVal;
因此您的代码将缩短为:
switch(wParam) {
case VK_F11:
flipVal = !flipVal;
break;
case VK_F12:
otherVal = !otherVal;
break;
default:
break;
}
显然你需要一个工厂模式!
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>
我发现的最简单的解决方案:
x ^= true;
如果您知道这些值为 0 或 1,您可以这样做
flipval ^= 1
。
仅供参考 - 如果您所需的字段不是整数,而是较大类型中的单个位,请改用“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;
只是因为我最喜欢的奇怪的切换布尔值的方法没有列出......
bool x = true;
x = x == false;
也有效。 :)
(是的,
x = !x;
更清晰易读)
这好像是一场混战……呵呵。这是另一个变体,我想它更属于“聪明”类别,而不是我推荐的生产代码:
flipVal ^= (wParam == VK_F11);
otherVal ^= (wParam == VK_F12);
我想它的优点是:
同样明显的缺点是
这接近@korona 使用 ?: 的解决方案,但又向前迈出了一小步。
codegolf'ish 的解决方案更像是:
flipVal = (wParam == VK_F11) ? !flipVal : flipVal;
otherVal = (wParam == VK_F12) ? !otherVal : otherVal;
flipVal ^= 1;
同样适用于
otherVal
我更喜欢 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;
显然您需要一个灵活的解决方案来支持伪装成布尔值的类型。以下允许这样做:
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 和 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;
}
只是因为我喜欢质疑代码。我建议您也可以通过执行以下操作来使用三元:
示例:
bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;
如果不引发 clang-tidy 的同义反复比较错误,我就无法让 boolean != boolean 或其任何变体工作。我的解决方案不是禁用警告(如果您要忽略警告,为什么要启用警告!),我的解决方案是在函数内添加一个小 lambda:
auto flip_boolean{ [](bool item) {
if (item == true) { return false; }
return true;
} };
这不仅否定了警告,而且我认为还提高了可读性,因为 Flip_boolean 明确地表达了所需的行为。编译器最终可能会优化它,所以没有必要在输入上节俭。