这是我将用来获取一组三个布尔值并将其转换为用于switch语句的int的代码:
int bits = 0;
bool a = true, b = false, c = true; // 101 = 5
bits = bits | a << 2;
bits = bits | b << 1;
bits = bits | c;
cout << bits;
根据这三种布尔值的总和状态,我有八种情况。我这样做了吗?
是的,不是语法意义上的,如果有任何问题请指教。更正确的是“这是解决这个问题的最好方法吗?”
答案 0 :(得分:4)
如果您使用的是C ++,则可以使用bitset<N>
。
答案 1 :(得分:1)
你做得对。你可以使代码更简洁:
bits |= (a<<2) | (b<<1) | (c<<0);
请注意,标准不对bool
强制执行任何大小限制。实际上,三位应该没有问题,但是标准不会在这里支持你。
答案 2 :(得分:1)
$ cat ttt.c
//example of C solution
#include <stdio.h>
int main() {
union {
unsigned int val;
struct {
unsigned a : 1;
unsigned b : 1;
unsigned c : 1;
//unsigned d : 1;
//e, f, g, h...
} flags;
} bits;
bits.val=0;
bits.flags.a = 1;
bits.flags.c = 1;
printf("val: %d\n",bits.val);
return 0;
}
〜$ ./ttt
val: 5
答案 3 :(得分:0)
您可以随时明确地进行转换:
bits = bits | (a ? 1 : 0) << 2;
但是我相信一旦你使用了位移运算符,C / C ++就会隐式处理它。
您应该为每个标志定义常量,为您设置的位指定名称:
const int a_flag = 2;
bits = bits | (a ? 1 : 0) << a_flag;
修改强>
从我对答案的评论中可以看出,大多数C / C ++程序员更喜欢学习隐式转换和运算符优先级。因此,您的原始代码是“最正确的”。
编辑2:
除此之外,您应该使用|=
运算符:
const int a_flag = 2;
bits |= a << a_flag;
答案 4 :(得分:0)
我会这样做:
bits = (bits << 1) | a;
bits = (bits << 1) | b;
bits = (bits << 1) | c;
如果您需要添加或删除标记,则需要较少的维护工作。
然而,这样做是为了让你可以将它用于switch
听起来像是一个坏主意。添加标志会使您需要处理的状态数量翻倍,case
值将变得脆弱且难以阅读。
但如果你真的必须,这是另一种方法:
enum
{
c_bit_offset,
b_bit_offset,
a_bit_offset
};
unsigned int bits = (a << a_bit_offset)
| (b << b_bit_offset)
| (c << c_bit_offset);
switch (bits)
{
case 0:
/* Do something. */
break;
case (1 << a_bit_offset):
/* Do something. */
break;
case (1 << a_bit_offset) | (1 << b_bit_offset):
/* Do something. */
break;
...
}
顺便说一下,您可能应该使用unsigned int
而不是int
。
答案 5 :(得分:0)
您可以制作一些定义以便于使用位
#define BitSet(arg,bit) ((arg) |= (1<<bit))
#define BitClr(arg,bit) ((arg) &= ~(1<<bit))
#define BitFlp(arg,bit) ((arg) ^= (1<<bit))
#define BitTst(arg,bit) ((arg) & (1<<bit))
然后你只能使用一个字符
keys = 0b00000101;
BitSet (keys,1);
这是在嵌入式系统中工作的常用方法。