2010-05-29 13 views
8

Durante la lettura di alcuni documenti here, mi sono imbattuto in questo:OR bit per bit delle costanti

unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 

Non ho idea di come funziona. Ho letto gli operatori bit a bit in C, ma non capisco come sia possibile inserire tre (o più!) Costanti all'interno di una int e dopo essere in grado di estrarle di nuovo dall'int? Scavando più in basso la documentazione, ho trovato anche questo, che è probabilmente legato:

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; 

Come le dichiarazioni (1 << 3)/variabili di lavoro? Mi dispiace se questo è banale, ma qualcuno potrebbe per favore illuminarmi spiegando o magari postando un link per una buona spiegazione?

+0

Sembra l'obiettivo-c? Questo è etichettato male? – SoapBox

+0

@SoapBox: l'esempio è effettivamente preso da Cocoa, ma è davvero diretto C. – ryyst

+0

Quella seconda riga di codice non è C, non da un punto lungo. – SoapBox

risposta

9

Fondamentalmente , le costanti sono rappresentate solo di un bit, quindi se hai un intero a 32 bit, puoi inserire 32 costanti in esso. Le tue costanti devono avere il potere di due, quindi prendono solo un bit "set" da rappresentare.

Ad esempio:

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

allora si può fare

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

Come si può vedere, ogni bit rappresenta quel particolare costante. Così si può binario e nel codice e test per la presenza di ogni costante, come:

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

vi consiglio di leggere su operazioni binarie (lavorano come operatori logici, ma a livello di bit), se si gira questa roba, ti renderà un po 'meglio un programmatore.

Cheers.

1

Il numero 1 è rappresentato come 00000000000000000000000000000001 (1 < < n) significa spostare le 1 nella rappresentazione 1 di n posti a sinistra del Così (1 < < 3) sarebbe 00000000000000000000000000001000 In un int si può avere 32 opzioni ognuno dei quali può essere attivato o disattivato. Opzione numero n è sul se il bit è n'th 1

2

Se si guarda a un numero in binario, ogni cifra è o su (1) o disattivare (0).

È possibile utilizzare gli operatori bit per bit per impostare o interrogare i singoli bit in modo efficiente per verificare se sono impostati o meno.

Prendere il valore a 8 bit 156. In binario è 10011100.

I bit impostati corrispondono ai bit 7, 4, 3 e 2 (valori 128, 16, 8, 4). È possibile calcolare questi valori con 1 << (position) piuttosto facilmente. Quindi, 1 << 7 = 128.

0

1 << y è fondamentalmente la stessa cosa di 2 to the power of y

Più in generale, x << y è la stessa cosa di x multiplied by 2 to the power of y.

In binari x << y mezzi di movimentazione tutti i bit di x a sinistra per y posti, aggiungendo zeri al posto dei bit spostati:

00010 << 2 = 01000

Quindi:

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

<< è l'operatore di spostamento a sinistra, sposta i bit del primo operando lasciato dal numero di posizioni specificato nell'operando di destra (con gli zeri che entrano nelle posizioni spostate da destra).

Nel vostro enum si finisce con valori che eacg hanno un po 'diverso impostato a 1, in modo che quando si costruisce qualcosa come unitDate, in seguito sarà possibile scoprire quali bandiere contiene utilizzando l'operatore &, per esempio unitDate & NSMonthCalendarUnit == NSMonthCalendarUnit sarà vero.

Problemi correlati