我正在查看我目前在项目中的代码,发现了类似的内容:
public enum MyEnum
{
open = 1 << 00,
close = 1 << 01,
Maybe = 1 << 02,
........
}
<<
操作数是移位操作数,它将第一个操作数左移第二个操作数中指定的位数。
但是为什么会有人在enum
声明中使用它?
答案 0 :(得分:40)
这允许你做这样的事情:
var myEnumValue = MyEnum.open | MyEnum.close;
无需计算2的倍数的位值。
(像这样):
public enum MyEnum
{
open = 1,
close = 2,
Maybe = 4,
........
}
答案 1 :(得分:22)
这通常与位域一起使用,因为它清楚模式是什么,无需手动计算正确的值,从而减少出错的可能性
[Flags]
public enum SomeBitField
{
open = 1 << 0 //1
closed = 1 << 1 //2
maybe = 1 << 2 //4
other = 1 << 3 //8
...
}
答案 2 :(得分:10)
避免手动输入Flags
枚举的值。
public enum MyEnum
{
open = 0x01,
close = 0x02,
Maybe = 0x04,
........
}
答案 3 :(得分:6)
这只是为了更清晰/更直观的写位方式。 1,2,3是比0x1,0x2,0x4等更易读的序列。
答案 4 :(得分:6)
这是为了制作一个可以组合的枚举。
这实际上意味着:
public enum MyEnum
{
open = 1;
close = 2;
Maybe = 4;
//...
}
这只是创建[Flags]
枚举的一种更加防弹的方法。
答案 5 :(得分:6)
这里有很多答案描述了这个机制允许你做什么,但不是为什么 你会想要使用它。这就是原因。
简短版:
此符号有助于与其他组件交互和通信 与其他工程师一起,因为它明确告诉你一个单词中的位是什么 设置或清除而不是在数值中隐藏该信息。
所以我可以打电话给你,然后说:“嘿,有什么可以打开的
文件?“你会说,”比特0“。我会写我的代码open = 1 << 0
。
因为<<
右侧的数字会告诉您位数。
长版:
传统上,单词中的位从右到左编号,从零开始。 因此,最不重要的位是位数0,并且随着您的进展,您会计数 最重要的一点。这有几个benefits到标记位 方式。
一个好处是,无论字大小,您都可以谈论相同的位。 例如,我可以说在32位字0x384A和8位字0x63中都是位 设置6和1。如果你在另一个方向编号你的位,你就不能 那样做。
另一个好处是,比特的值只是2比特的功率
位置。例如,二进制0101
具有位2和0集。第2位贡献了
值4 (2^2)
到数字,位0贡献值1(2 ^ 0)。所以
数字的值当然是4 + 1 = 5.
这种冗长的背景解释让我们明白了一点:<<
符号只是通过查看它来告诉你位数。
语句1 << n
中的数字1本身只是一个位设置
位置0.当你向左移动那个数字时,你就会移动那个数字
位到数字的不同位置。方便的是,你转移的金额
告诉你将要设置的位号。
1 << 5: This means bit 5. The value is 0x20.
1 << 12: This means bit 12. The value is 0x40000.
1 << 17: This means bit 17. The value is 0x1000000.
1 << 54: This means bit 54. The value is 0x40000000000000.
(You can probably see that this notation might be helpful if
you're defining bits in a 64-bit number)
当你与另一个人互动时,这种符号真的很方便
组件,就像将字中的位映射到硬件寄存器一样。像你一样
有一个设备在你写入第7位时打开。所以硬件工程师
会写一个数据表,说第7位启用设备。你会写的
你的代码ENABLE = 1 << 7
。很简单。
ENABLE = 1 << 15
。
如果同时设置了第7位和第1位,ENABLE
实际上是什么?
ENABLE = (1 << 7) | (1 << 1)
。
起初可能看起来很奇怪和迟钝,但你会习惯它。你会的 如果您明确需要知道某些内容的位数,请欣赏它。
答案 6 :(得分:0)
它相当于两个人的力量。
public enum SomeEnum
{
Enum1 = 1 << 0, //1
Enum2 = 1 << 1, //2
Enum3 = 1 << 2, //4
Enum4 = 1 << 3 //8
}
有了这样的枚举,你将拥有如下所示的功能:
void foo(unsigned ind flags)
{
for (int = 0; i < MAX_NUMS; i++)
if (1 << i & flags)
{
//do some stuff...
//parameter to that stuff probably is i either enum value
}
}
对该函数的调用将是foo(Enum2 | Enum3);
,它将对所有给定的枚举值执行某些操作。