2012-05-08 87 views
86

Tôi khá mới đối với lập trình C và tôi đã gặp phải một số mặt nạ bit. Ai đó có thể giải thích cho tôi khái niệm chung và chức năng của bit masking? Ví dụ được nhiều người đánh giá cao.Bit Masking là gì?

+0

Bạn hiểu các toán tử bitwise như & |^vv và logic Boolean nói chung? Bất kỳ giải thích về hoạt động mặt nạ sẽ yêu cầu này. –

+0

Có Tôi hiểu rõ về các toán tử bitwise và logic boolean –

+1

Tôi biết các liên kết không được đăng, nhưng giải thích wikipedia là tuyệt vời: https://en.wikipedia.org/wiki/Mask_(computing) – pevik

Trả lời

126

Mặt nạ xác định các bit bạn muốn giữ và các bit bạn muốn xóa.

Tạo mặt nạ là hành vi áp dụng mặt nạ cho giá trị. Này được thực hiện bằng cách thực hiện:

  • Bitwise ANDing để trích xuất một tập hợp con của các bit trong giá trị
  • Bitwise ORing để thiết lập một tập hợp con của các bit trong giá trị
  • Bitwise XORing theo thứ tự để chuyển đổi một tập hợp con của các bit trong giá trị

Dưới đây là một ví dụ về giải nén một tập hợp con của các bit trong giá trị:

Mask: 00001111b 
Value: 01010101b 

Áp dụng mặt nạ cho giá trị có nghĩa là chúng tôi muốn xóa 4 bit đầu tiên (cao hơn) và giữ 4 bit cuối cùng (thấp hơn). Vì vậy, chúng tôi đã trích xuất 4 bit thấp hơn. Kết quả là:

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

Masking được thực hiện sử dụng AND, vì vậy trong C ta có:

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

Đây là một trường hợp sử dụng khá phổ biến: Extracting byte cá nhân từ một từ lớn hơn. Chúng tôi xác định các bit có thứ tự cao trong từ là byte đầu tiên. Chúng tôi sử dụng hai toán tử cho điều này, &>> (dịch chuyển sang phải). Đây là cách chúng ta có thể trích xuất bốn byte từ một số nguyên 32-bit:

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 
    ... 
} 

Chú ý rằng bạn có thể chuyển đổi thứ tự của các nhà khai thác trên, đầu tiên bạn có thể làm mặt nạ, sau đó sự thay đổi. Các kết quả giống nhau, nhưng bây giờ bạn sẽ phải sử dụng một mặt nạ khác:

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

Câu trả lời hay nhưng có thể che giấu cũng được áp dụng cho * setting * hoặc * toggling * các bit cụ thể với các hoạt động OR hoặc XOR và một mặt nạ thích hợp. –

+0

@ user239558 cảm ơn ví dụ và cú pháp thích hợp. @ Paul R. Tôi chỉ đơn giản là nói mặt nạ và giá trị trong ví dụ được cung cấp bởi user239558 –

+0

@ Mr.Z: trong C, C++ và các ngôn ngữ liên quan bạn sẽ là toán tử ** bitwise AND **, được viết là '&'. –