这个声明是什么意思?
我不是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为Right
) 0010 & 0001 = 0
,这是我们所期望的错误(因此,你已经确定它是不正确的types)。 但是,如果控制器是0011 & 0001 = 1
所以结果是真的,这是正确的,因为我们确定这是Both
types。