2012-05-08 13 views
86

Jestem dość nowy w programowaniu w języku C i natrafiłem na maskowanie bitowe. Czy ktoś może mi wyjaśnić ogólną koncepcję i funkcję maskowania bitowego? Przykłady są doceniane.Co to jest maskowanie bitowe?

+0

Czy znasz operatory bitowe, takie jak & |^etc i logika Boole'a w ogóle? Wszelkie wyjaśnienia dotyczące operacji na maskach będą tego wymagały. –

+0

Tak Mam rozumieć operatorów bitowych i logiki Boole'a –

+1

Wiem, że łącza nie powinny być publikowane, ale wyjaśnienie wikipedii jest świetne: https://en.wikipedia.org/wiki/Mask_(computing) – pevik

Odpowiedz

126

Maska określa, które bity chcesz zachować i które bity chcesz wyczyścić.

Maskowanie jest aktem stosowania maski do wartości. Osiąga się to przy pomocy:

  • mnożenie logiczne w celu wyodrębnienia podzestaw bitów wartości
  • sumowanie logiczne w celu ustalenia podzestaw bitów wartości
  • Bitowe XORing w celu przełączyć się podzestaw bitów wartości

Poniżej przedstawiono przykład ekstrakcji podzestaw bitów wartości:

Mask: 00001111b 
Value: 01010101b 

Zastosowanie maski do wartości oznacza, że ​​chcemy wyczyścić pierwsze (wyższe) 4 bity i zachować ostatnie (niższe) 4 bity. W ten sposób wyodrębniliśmy niższe 4 bity. Wynikiem jest:

Mask: 00001111b 
Value: 01010101b 
Result: 00000101b 

Maskowanie jest realizowany za pomocą I tak w C otrzymujemy:

uint8_t stuff(...) { 
    uint8_t mask = 0x0f; // 00001111b 
    uint8_t value = 0x55; // 01010101b 
    return mask & value; 
} 

Tutaj jest dość powszechne stosowanie-case: Wyodrębnianie poszczególnych bajtów z większego wyrazu. Bity wyższego rzędu definiujemy w słowie jako pierwszy bajt. Używamy do tego dwóch operatorów: & i >> (przesunięcie w prawo). W ten sposób możemy wyodrębnić cztery bajty z 32-bitowej liczby całkowitej:

void more_stuff(uint32_t value) {    // Example value: 0x01020304 
    uint32_t byte1 = (value >> 24);   // 0x01020304 >> 24 is 0x01 so 
               // no masking is necessary 
    uint32_t byte2 = (value >> 16) & 0xff; // 0x01020304 >> 16 is 0x0102 so 
               // we must mask to get 0x02 
    uint32_t byte3 = (value >> 8) & 0xff; // 0x01020304 >> 8 is 0x010203 so 
               // we must mask to get 0x03 
    uint32_t byte4 = value & 0xff;   // here we only mask, no shifting 
               // is necessary 
    ... 
} 

Uwaga, można zmienić kolejność operatorów powyżej, można najpierw zrobić maskę, a następnie przesunięcie. Wyniki są takie same, ale teraz musiałbyś użyć innej maski:

uint32_t byte3 = (value & 0xff00) >> 8; 
+0

Dobra odpowiedź, ale maskowanie można również zastosować do * ustawiania * lub * przełączania * określonych bitów za pomocą operacji OR lub XOR i odpowiedniej maski. –

+0

@ user239558 dzięki za przykład i prawidłową składnię. @ Paul R. Czy po prostu powiem maskę i wartość w przykładzie podanym przez user239558 –

+0

@ Mr.Z: w C, C++ i językach pokrewnych będziesz ** operatorem AND **, który jest zapisywany jako '&'. –