这个声明是什么意思?

时间:2013-03-29 17:41:09

标签: ios objective-c c cocoa-touch cocoa

我不是C / C ++的专家。

我今天发现了这个声明:

typedef NS_OPTIONS(NSUInteger, PKRevealControllerType)
{
    PKRevealControllerTypeNone  = 0,
    PKRevealControllerTypeLeft  = 1 << 0,
    PKRevealControllerTypeRight = 1 << 1,
    PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft | PKRevealControllerTypeRight)
};

你们可以翻译每个价值的价值吗?

4 个答案:

答案 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(即类型为Right0010 & 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时。