这个声明是什么意思?

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

我今天发现了这个声明:

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

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

opertor <<是左移位运算符。 将所有位左移一个指定的次数:(算术左移并保留符号位)

 m << n 

m所有位左移n次。 ( 注意一class==乘以二 )。

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除了像图1之外什么都不做。 (注意第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 

没有更多的技术理由来初始化像这样的值,定义如此使得事情很好地排列,读取这个答案: define SOMETHING(1 << 0)

编译器优化转换他们更简单的像:( 我不知道第三个,但我认为编译器也将优化

 PKRevealControllerTypeNone = 0, // is Zero PKRevealControllerTypeLeft = 1, // one PKRevealControllerTypeRight = 2, // two PKRevealControllerTypeBoth = 3, // Three 

编辑: @感谢直到。 阅读这个答案BOOL标志的应用程序状态显示您使用位明智的运算符的声明的有用性。

这是一个比特标志的枚举:

 PKRevealControllerTypeNone = 0 // no flags set PKRevealControllerTypeLeft = 1 << 0, // bit 0 set PKRevealControllerTypeRight = 1 << 1, // bit 1 set 

接着

 PKRevealControllerTypeBoth = (PKRevealControllerTypeLeft | PKRevealControllerTypeRight) 

只是将其他两个标志按位“或”的结果。 所以,位0和位1设置。

<<运算符是左移运算符。 和| 运算符是按位或。

总之,结果值是:

 PKRevealControllerTypeNone = 0 PKRevealControllerTypeLeft = 1 PKRevealControllerTypeRight = 2 PKRevealControllerTypeBoth = 3 

但是根据比特标志来考虑它更有意义。 或者作为通用集的集合:{PKRevealControllerTypeLeft,PKRevealControllerTypeRight}

要了解更多信息,您需要阅读关于枚举,转换运算符和按位运算符。

这看起来像Objective C而不是C ++,但不pipe:

 1 << 0 

只是一个左移位(向上)0位置。 任何整数“<< 0”就是其本身。

所以

 1 << 0 = 1 

同样

 1 << 1 

只是一个位置左移一位而已。 你可以用多种方式来形象化,但最简单的就是乘以2. [注1]

所以

 x << 1 == x*2 

要么

 1 << 1 == 2 

最后单pipe操作员是一个按位或 。

所以

 1 | 2 = 3 

TL;博士:

 PKRevealControllerTypeNone = 0 PKRevealControllerTypeLeft = 1 PKRevealControllerTypeRight = 2 PKRevealControllerTypeBoth = 3 

[1]这种泛化有一些限制,例如当x等于或大于数据types能够存储的最大值的1/2时。

这一切都归结为按位算术。

PKRevealControllerTypeNone的值为0(二进制0000)

PKRevealControllerTypeLeft的值为1(二进制0001)

由于0001向左移动1位是0010,PKRevealControllerTypeRight的值为2(二进制0010)

从0010开始,PKRevealControllerTypeBoth的值为3(二进制0011) 0001(或者像加法一样)= 0011

在上下文中,这很可能用于确定一个值。 该属性是(或bitwise-and )与乘法运算相似。 如果1和一个数字相同,那么这个数字将被保留,如果0和一个数字相同,那么这个数字就被清除了。

因此,如果你想检查一个特定的控制器是否是特定types的Left ,它的值是0010 (即types为Right0010 & 0001 = 0 ,这是我们所期望的错误(因此,你已经确定它是不正确的types)。 但是,如果控制器是0011 & 0001 = 1所以结果是真的,这是正确的,因为我们确定这是Bothtypes。