常数的按位OR

时间:2010-05-29 20:23:41

标签: c operators bit-manipulation

在阅读一些文档here时,我发现了这个:

unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;

我不知道这是如何运作的。我读了C中的按位运算符,但我不明白你如何在一个int中包含三个(或更多!)常量,以后能够以某种方式从int中提取它们?进一步深入了解文档,我也发现了这一点,这可能是相关的:

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),
} CFCalendarUnit;

(1 << 3)语句/变量如何工作?我很抱歉,如果这是微不足道的,但有人可以通过解释或者发布一个好的解释链接来启发我吗?

5 个答案:

答案 0 :(得分:9)

基本上,常量只用一位表示,所以如果你有一个32位整数,你可以在其中输入32个常量。你的常数必须是2的幂,所以它们只需要一个“set”位代表。

例如:

#define CONSTANT_1 0x01 // 0001 in binary
#define CONSTANT_2 0x02 // 0010 in binary
#define CONSTANT_3 0x04 // 0100 in binary

然后你可以做

int options = CONSTANT_1 | CONSTANT_3; // will have 0101 in binary.

如您所见,每个位代表该特定常量。因此,您可以在代码中使用二进制AND并测试每个常量的存在,例如:

if (options & CONSTANT_3)
{
    // CONSTANT_3 is set
}

我建议你阅读二进制操作(它们像LOGICAL操作符一样工作,但是在位级别),如果你理解这些东西,它会让你对程序员更好。

干杯。

答案 1 :(得分:2)

如果您查看二进制数字,则每个数字都在(1)或关闭(0)上。

您可以使用按位运算符有效地设置或查询各个位,以查看它们是否已设置。

取8位值156.在二进制中,这是10011100

设置位对应于位7432(值12816,{{1 },8)。您可以使用4轻松计算这些值。所以,1 << (position) = 1 << 7

答案 2 :(得分:1)

数字1表示为00000000000000000000000000000001 (1&lt;&lt; n)意味着将1对1的表示n位置向左移位 因此(1 <3)将是00000000000000000000000000001000 在一个int中,您可以有32个选项,每个选项都可以打开或关闭。 如果第n位为1

,则选项编号n打开

答案 3 :(得分:0)

1 << y2 to the power of y

基本相同

更一般地说,x << yx multiplied by 2 to the power of y相同。

二进制x << y表示将x的所有位向左移动y个位置,在移动位的位置添加零:

00010 << 2 = 01000

所以:

1 << 1 = 2
1 << 2 = 4
1 << 3 = 8
...

答案 4 :(得分:0)

<<是左移位运算符,它将第一个操作数的位移位右操作数中指定的位置数(零从右侧进入移位位置)。

在你的枚举中,你得到的结果是eacg的不同位设置为1,所以当你构造像unitDate这样的东西时,你可以稍后使用&找出它包含哪些标志。运营商,例如unitDate & NSMonthCalendarUnit == NSMonthCalendarUnit将是真的。