【问题标题】:enum objective-C and "<<" operator [duplicate]枚举objective-C和“<<”运算符[重复]
【发布时间】:2013-08-03 22:11:47
【问题描述】:

我正在阅读NSCalendar 的文档,出于好奇,我更深入地研究了CFCalendarUnit,我看到了这个:

typedef enum {
   kCFCalendarUnitEra = (1 << 1),
   kCFCalendarUnitYear = (1 << 2),
   kCFCalendarUnitMonth = (1 << 3),
   kCFCalendarUnitDay = (1 << 4),
   kCFCalendarUnitHour = (1 << 5),
   kCFCalendarUnitMinute = (1 << 6),
   kCFCalendarUnitSecond = (1 << 7),
   kCFCalendarUnitWeek = (1 << 8),
   kCFCalendarUnitWeekday = (1 << 9),
   kCFCalendarUnitWeekdayOrdinal = (1 << 10),
   kCFCalendarUnitQuarter = (1UL << 11),
   kCFCalendarUnitWeekOfMonth = (1UL << 12),
   kCFCalendarUnitWeekOfYear = (1UL << 13),
   kCFCalendarUnitYearForWeekOfYear = (1UL << 14),
} CFCalendarUnit;

我是这样使用的:

NSUInteger preservedComponents = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;

它返回124

所以我尝试这样做:

NSUInteger preservedComponents = NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;

我得到30

我想不通。它是如何工作的?

【问题讨论】:

  • 2+3+8+16 = 30. 2 + 4 + 8 + 16 + 32 + 64 = 124。你的问题到底是什么?自然地,按位或操作数恰好等价于 +,因为每个操作数中始终只有一个唯一的位。
  • 是的,在你下面有很多人回答之前。只是要清楚... 2+3+8+16 不是 30... 2+4+8+16 是。
  • 是的,当然,我的意思是写2+4+8...

标签: c++ ios objective-c enums typedef


【解决方案1】:

这些只是二进制数。 1 &lt;&lt; n 是一个二进制数,1n-th 位置,其他位置为零。要计算其中几个 OR-ed 的值,请编写一个二进制数,其位置对应于 1 在其定义中移动了多少个位置,并将该数字转换为十进制表示。

例如,

NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit

1(纪元)、2(年)、3(月)和4(日)位置有一个,并且所有剩余位置都为零;位置从右侧开始从零开始编号。它看起来像这样:

Position:  76543210
           --------
Bit value: 00011110

这个二进制表示的00011110 是十进制表示的30

【讨论】:

    【解决方案2】:

    枚举使用按位移位操作 (wiki) 来生成值,每个值在用于存储枚举值的“int”中仅设置一位。通过这样做,您可以对这些值进行 OR(按位运算),并且仍然能够判断设置了哪些选项。

    preservedComponents 视为一个实际数字确实意味着什么,但这并不是很明显,因为它的意思是一组指定格式/掩码的选定位。

    【讨论】:

      【解决方案3】:

      当你写(1 &lt;&lt; k) 时,你会发现只有第 k 个(从右边开始,从 0 开始)位被打开。如果你写(1 &lt;&lt; a) | (1 &lt;&lt; b),你会得到只有a-th和b-th位被设置。

      例如,当您获得 124 时,您正在处理二进制数 1111100。这意味着您以这种方式将数字组合在一起(OR 运算符)

      (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (i << 6)
      

      我不知道这对您的符号名称意味着什么,因为您似乎复制了错误的枚举。但我相信你明白了! :)

      【讨论】:

        【解决方案4】:

        | 是按位或运算符。它采用两个长度相等的位模式,并对每对相应的位执行逻辑异或运算。所以说一下,它需要 NSYearCalendarUnit、NSMonthCalendarUnit 等并执行 OR 运算,从而产生您的 12430。这是将标志组合作为参数传递的非常常见的方式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-18
          • 2011-11-18
          • 2013-12-21
          • 1970-01-01
          • 2011-02-04
          • 1970-01-01
          相关资源
          最近更新 更多