2010-05-29 10 views
8

Czytając niektóre dokumentacji here, natknąłem się na to:bitowe OR stałych

unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 

nie mam pojęcia jak to działa. Czytałem operatory bitowe w C, ale nie rozumiem, w jaki sposób można dopasować trzy (lub więcej!) Stałe wewnątrz jednej int, a później można je w jakiś sposób wydobyć z powrotem z int? Kopanie w dalszej części dokumentacji, znalazłem również to, co jest prawdopodobnie związane:

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; 

jaki sposób oświadczenia (1 << 3)/zmienne działa? Przepraszam, jeśli to banalne, ale czy ktoś mógłby mnie oświecić, wyjaśniając, a może zamieszczając link do dobrego wyjaśnienia?

+0

To wygląda jak cel-c? Czy to jest źle oznakowane? – SoapBox

+0

@SoapBox: Przykład rzeczywiście pochodzi z Cocoa, ale naprawdę jest prosty C. – ryyst

+0

Ta druga linia kodu to nie C, a nie długie ujęcie. – SoapBox

Odpowiedz

9

Zasadniczo , stałe są reprezentowane tylko przez jeden bit, więc jeśli masz 32-bitową liczbę całkowitą, możesz zmieścić 32 stałe w nim. Twoje stałe muszą być potęgami dwóch, więc biorą tylko jeden "ustawiony" bit do przedstawienia.

Na przykład:

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

wtedy można zrobić

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

Jak widać, każdy bit reprezentuje ten konkretny stała. Więc można binarny i w kodzie i test na obecność każdej stałej, jak:

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

Polecam poczytać o operacji binarnych (działają one jak operatory logiczne, ale na poziomie bitowym), jeśli Grok ten rzeczy, będzie ci nieco lepiej od programisty.

Pozdrawiam.

1

Numer 1 jest przedstawiony jako 00000000000000000000000000000001 (1 < < n) oznacza przesunięcie 1 na 1 w reprezentacji n miejsc do lewej SO (1 < < 3) byłoby 00000000000000000000000000001000 W jednym int można mieć 32 opcji z których każdy można włączyć lub wyłączyć. liczba n jest opcja jeśli n'th bit jest 1

2

Jeśli spojrzeć na liczbę binarną, każda cyfra jest albo na (1) lub wyłączyć (0).

Można użyć operatorów bitowych, aby efektywnie ustawić lub przeskanować poszczególne bity, aby sprawdzić, czy są ustawione, czy nie.

Weź 8-bitową wartość 156. W systemie binarnym jest to 10011100.

SET bitów odpowiadają bitów 7, 4, 3 i 2 (wartości 128, 16, 8, 4). Możesz łatwo obliczyć te wartości za pomocą 1 << (position). Tak więc, 1 << 7 = 128.

0

1 << y jest w zasadzie to samo, co 2 to the power of y

Bardziej ogólnie, x << y to samo, co x multiplied by 2 to the power of y.

W binarnych x << y ruchomym wszystkie bity x w lewo o y miejscach, dodając zera w miejscu przeniesionego bitów:

00010 << 2 = 01000

Więc:

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

<< jest operatorem przesuniętym w lewo, przesuwa bity pierwszego operandu w lewo o liczbę pozycji określoną w prawym argumencie (z zerami wchodzącymi w przesunięte pozycje od prawej).

W twoim wyliczeniu kończą się wartości, które eacg mają inny bit ustawiony na 1, więc gdy skonstruujesz coś takiego jak unitDate, możesz później dowiedzieć się, które znaczniki zawiera, używając operatora &, np. unitDate & NSMonthCalendarUnit == NSMonthCalendarUnit będzie prawdą.