我不是C / C ++的专家。
我今天发现了这个声明:
typedef NS_OPTIONS(NSUInteger, PKRevealControllerType)
{
PKRevealControllerTypeNone = 0,
PKRevealControllerTypeLeft = 1 << 0,
PKRevealControllerTypeRight = 1 << 1,
PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft | PKRevealControllerTypeRight)
};
你们可以翻译每个价值的价值吗?
答案 0 :(得分:5)
opertor <<
是按位左移位运算符。将所有位移位指定的次数:(算术左移和保留符号位)
m << n
将m
的所有位移到n
次{000}。 (注意一个班次==乘以两个)。
1 << 0
表示没有转换,因此它仅等于1
。
1 << 1
表示一个班次,因此它仅等于1*2
= 2。
我用一个字节解释:一个字节中的一个像:
MSB
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1
+----+----+----+---+---+---+---+---+
7 6 5 4 3 2 1 / 0
| / 1 << 1
| |
▼ ▼
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2
+----+----+----+---+---+---+---+---+
7 6 5 4 3 2 1 0
1 << 0
除了类似图一之外什么都不做。 (注意第7位被复制以保留标志)
OR运算符:有点明智或
MSB PKRevealControllerTypeLeft
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | == 1
+----+----+----+---+---+---+---+---+
7 6 5 4 3 2 1 0
| | | | | | | | OR
MSB PKRevealControllerTypeRight
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | == 2
+----+----+----+---+---+---+---+---+
7 6 5 4 3 2 1 0
=
MSB PKRevealControllerTypeBoth
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | == 3
+----+----+----+---+---+---+---+---+
7 6 5 4 3 2 1 0
|
是比特明智的运算符。在下面的代码or
1 | 2
== 3
PKRevealControllerTypeNone = 0, // is Zero
PKRevealControllerTypeLeft = 1 << 0, // one
PKRevealControllerTypeRight = 1 << 1, // two
PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft |
PKRevealControllerTypeRight) // three
没有更多的技术理由来初始化这样的值,这样定义可以很好地理解这个答案:define SOMETHING (1 << 0)
编译器优化将它们转换为更简单的类似:(我不确定第三个,但我认为编译器也会优化它)
PKRevealControllerTypeNone = 0, // is Zero
PKRevealControllerTypeLeft = 1, // one
PKRevealControllerTypeRight = 2, // two
PKRevealControllerTypeBoth = 3, // Three
编辑: @谢谢直到。 阅读此答案App States with BOOL flags显示使用逐位运算符获得的声明的有用性。
答案 1 :(得分:3)
这是位标志的枚举:
PKRevealControllerTypeNone = 0 // no flags set
PKRevealControllerTypeLeft = 1 << 0, // bit 0 set
PKRevealControllerTypeRight = 1 << 1, // bit 1 set
然后
PKRevealControllerTypeBoth =
(PKRevealControllerTypeLeft | PKRevealControllerTypeRight)
只是对其他两个标志进行按位OR运算的结果。所以,位0和位1设置。
<<
运算符是左移运算符。 |
运算符是按位OR。
总之,结果值是:
PKRevealControllerTypeNone = 0
PKRevealControllerTypeLeft = 1
PKRevealControllerTypeRight = 2
PKRevealControllerTypeBoth = 3
但从比特标志的角度思考它会更有意义。或者作为通用集的集合:{PKRevealControllerTypeLeft,PKRevealControllerTypeRight}
要了解更多信息,您需要阅读有关枚举,移位运算符和按位运算符的信息。
答案 2 :(得分:2)
这一切都归结为逐位算术。
PKRevealControllerTypeNone的值为0(二进制0000)
PKRevealControllerTypeLeft的值为1(二进制0001)
PKRevealControllerTypeRight的值为2(二进制0010),因为0001左移1位是0010
自0010 |以来,PKRevealControllerTypeBoth的值为3(二进制0011) 0001(或类似的补充)= 0011
在上下文中,这很可能用于确定值。属性&
(或bitwise-and
)与乘法类似。如果1
和带有数字,则保留该数字,如果0
并带有数字,则清除该数字。
因此,如果要检查特定控制器是否具体为Left
类型且值为0010
(即类型为Right
)0010 & 0001 = 0
为假正如我们所期望的那样(因此,您已确定它的类型不正确)。但是,如果控制器为Both
0011 & 0001 = 1
,那么结果为真,这是正确的,因为我们确定这是Both
类型。
答案 3 :(得分:2)
这看起来像Objective C而不是C ++,但无论如何:
1 << 0
只有一个位左移(向上)0位置。任何整数“&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; 0&gt
所以
1 << 0 = 1
类似地
1 << 1
只有1位左移1位。您可以通过多种方式可视化,但最简单的方法是乘以2. [注1]
所以
x << 1 == x*2
或
1 << 1 == 2
最后,单管道运算符是bitwise or。
所以
1 | 2 = 3
TL; DR:
PKRevealControllerTypeNone = 0
PKRevealControllerTypeLeft = 1
PKRevealControllerTypeRight = 2
PKRevealControllerTypeBoth = 3
[1]这种泛化存在一些限制,例如当x
等于或大于能够由数据类型存储的最大值的1/2时。