我一直在寻找在目前,我有我的项目中的代码,发现是这样的:为什么有人在枚举声明中使用<<运算符?
public enum MyEnum
{
open = 1 << 00,
close = 1 << 01,
Maybe = 1 << 02,
........
}
的<<
操作数是移位操作数,移动通过在第二个操作数指定的位数留下的第一个操作数。
但是为什么有人会在enum
声明中使用它?
我一直在寻找在目前,我有我的项目中的代码,发现是这样的:为什么有人在枚举声明中使用<<运算符?
public enum MyEnum
{
open = 1 << 00,
close = 1 << 01,
Maybe = 1 << 02,
........
}
的<<
操作数是移位操作数,移动通过在第二个操作数指定的位数留下的第一个操作数。
但是为什么有人会在enum
声明中使用它?
这允许你做这样的事情:
var myEnumValue = MyEnum.open | MyEnum.close;
无需计算的2
倍数位值(像这样):
public enum MyEnum
{
open = 1,
close = 2,
Maybe = 4,
........
}
**注意**:['<<'声明会给你最多达64个不同的状态(在大多数平台上)。如果您需要更多可能的状态,这种解决方案将无法正常工作(http://stackoverflow.com/questions/8956364/app-states-with-bool-flags?answertab=votes#8956606) –
什么替代的解决方案将给予超过64个正交状态? – Useless
@GrijeshChauhan大多数平台?这是C#,所以整数类型的大小不依赖于平台。 << <<'运算符的左操作数的类型决定了要使用哪个超载。例如,用's'表示一个整数,'1 << s'表示一个32位'int','1u << s'表示32位无符号'uint','1L << s'表示64位'long','1UL << s'是'ulong'和'(的BigInteger)1 << s'或'BigInteger.One << s'给出了一个任意大小的整数(需要参照'System.Numerics.dll '大会)。 –
的机会/更直观的书写方式。 1,2,3是比0x1,0x2,0x4等更易读的序列。
为了避免手动输入Flags
enum的值。
public enum MyEnum
{
open = 0x01,
close = 0x02,
Maybe = 0x04,
........
}
+1。人们可能会在这样的'enum'上标明'[Flags]来澄清用法......但不是每个人都在意。 –
这是使一个枚举,你可以结合。
什么它实际上意味着是这样的:
public enum MyEnum
{
open = 1;
close = 2;
Maybe = 4;
//...
}
这仅仅是创建一个[Flags]
枚举的更稳固的方法。
很多答案在这里描述这个机制允许你做什么,但不是为什么你会想要使用它。这是为什么。
短版:
与其他组件进行交互和沟通 与其他工程师,因为它会告诉你明确什么位的字是 组或明确的而不是模糊内的信息时,该符号帮助数值。
所以我可以打电话给你,说“嘿,打开 文件是什么位?”你会说,“位0”。我会在我的代码open = 1 << 0
中写下。 因为<<
右边的数字告诉你位数。
。
龙版本:
传统的字位从右到左编号,从零开始。 所以最不重要的位是位数0,并且当你朝着最高位 进行计数。有几种benefits来标记位,这种方式是 。
一个好处是,无论字的大小如何,您都可以谈论相同的位。例如,我可以说在32位字0x384A和8位字0x63中都设置了位 6和1。如果你在另一个方向编号,你不能这样做。
另一个好处是,一个位的值是简单地提高到位 位的功率。例如,二进制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
。那样容易。
哦拍。该工程师刚刚向数据表发送勘误表示它是 应该是位15,而不是位7.没关系,只需将代码更改为 ENABLE = 1 << 15
。
如果ENABLE
实际上是在第7位和第1位同时置位时该怎么办?
ENABLE = (1 << 7) | (1 << 1)
。
起初它可能看起来很古怪,但你会习惯的。如果你明确需要知道某些东西的位数,那么你会很感激它。
它等于两个幂。
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);
,它会做所有给定枚举值的东西。
我不知道谁会投票结束这件事,但这不是一个“主要基于意见的”问题。这是一个技术性问题,具体询问'<<'在这种情况下的用途。 –
@GrantWinney(不是我的票接近),但我看到它是如何“意见为基础的”,因为这个问题本质上是“为什么有人使用'1 << 2'时'0x04'更具有可读性*我*”。 –
我从来没有说过0x04更具可读性,我也没有比较过。这个问题的目的是了解这句话的副作用(=能够标志结合使用) – JSBach