我不是在C / C专家++。
我今天发现这个声明:
typedef NS_OPTIONS(NSUInteger, PKRevealControllerType)
{
PKRevealControllerTypeNone = 0,
PKRevealControllerTypeLeft = 1 << 0,
PKRevealControllerTypeRight = 1 << 1,
PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft | PKRevealControllerTypeRight)
};
你们可以翻译什么值的每一个值都会有?
算子的<<
是按位左移运算。 移所有位到左的指定次数:(算术左移和储备符号位)
m << n
移的所有位m
向左一个n
的次数。 ( 注意用两个一个移位==乘 )。
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
1 | 2
== 3
PKRevealControllerTypeNone = 0, // is Zero
PKRevealControllerTypeLeft = 1 << 0, // one
PKRevealControllerTypeRight = 1 << 1, // two
PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft |
PKRevealControllerTypeRight) // three
没有更多的技术理由来这样的初始化值,定义这样使事情排队很好地阅读这样的回答: 就定义了(1 << 0)
编译器优化转换他们简单的,如:( 我不知道第三一个,但我认为编译器将优化太 )
PKRevealControllerTypeNone = 0, // is Zero
PKRevealControllerTypeLeft = 1, // one
PKRevealControllerTypeRight = 2, // two
PKRevealControllerTypeBoth = 3, // Three
编辑:@thanks至T111。 阅读这个答案应用国BOOL标志证明你有使用逐位运算符声明的有效性。
这是位标志的枚举:
PKRevealControllerTypeNone = 0 // no flags set
PKRevealControllerTypeLeft = 1 << 0, // bit 0 set
PKRevealControllerTypeRight = 1 << 1, // bit 1 set
然后
PKRevealControllerTypeBoth =
(PKRevealControllerTypeLeft | PKRevealControllerTypeRight)
是按位的只是结果的OR-ing其他两个标志。 因此,位0和位1套。
在<<
运算符是左移位运算符。 而|
运营商是位或。
总之,得到的值是:
PKRevealControllerTypeNone = 0
PKRevealControllerTypeLeft = 1
PKRevealControllerTypeRight = 2
PKRevealControllerTypeBoth = 3
但它使很多更有意义去想它在位标志的条款。 或一组,其中全集为:{PKRevealControllerTypeLeft,PKRevealControllerTypeRight}
要了解更多信息,你需要阅读了有关枚举,移位运算符和位运算符。
这看起来像目标C而不是C ++,但是不管:
1 << 0
只是一个bitshifted 0位置左(上)。 任何整数“<< 0”只是本身。
所以
1 << 0 = 1
同样
1 << 1
只是一个bitshifted 1个职位离开。 你可以想象多种方式,但最简单的是由2乘以[注1]
所以
x << 1 == x*2
要么
1 << 1 == 2
最后一个单独的管道运营商是按位或 。
所以
1 | 2 = 3
TL;博士:
PKRevealControllerTypeNone = 0
PKRevealControllerTypeLeft = 1
PKRevealControllerTypeRight = 2
PKRevealControllerTypeBoth = 3
[1]上有这种概括一些限制,例如,当x
是等于或能够被存储由数据类型大于1/2的最大值。
这一切都归结为按位运算。
PKRevealControllerTypeNone具有0(二进制0000)的值
PKRevealControllerTypeLeft具有为1的值(二进制0001)
PKRevealControllerTypeRight具有2(二进制0010)的值,因为0001左移1位为0010
PKRevealControllerTypeBoth具有3(二进制0011)的值,因为0010 | 0001(或工作方式类似加成)= 0011
在上下文中,这是最有可能用来确定一个值。 该物业是&
(或bitwise-and
)的工作原理类似乘法。 如果1
ANDS有一个数字,然后数被保留,如果0
行逻辑与数字,那么这个数被清除。
因此,如果要检查是否一个特定的控制器,具体键入Left
和它具有值0010
(即键入Right
) 0010 & 0001 = 0
,因为我们预计这是假的(因此,你已经确定它是正确的类型的不)。 然而,如果控制器是Both
0011 & 0001 = 1
这样的结果是真这是正确的,因为我们确定这是Both
类型的。