我如何在C ++中使用它?
何时使用有用?
请给我一个使用位掩码的问题示例,它实际上是如何工作的。
谢谢!
答案 0 :(得分:101)
简单地说,位掩码有助于操纵多个值的位置。这里有一个很好的例子;
Bitflags是一种在一个变量中存储多个不相互排斥的值的方法。你以前可能已经看过了。每个标志都是一个位置,可以设置为开或关。然后,每个位位置都有一堆位掩码#defined,以便您可以轻松操作它:
#define LOG_ERRORS 1 // 2^0, bit 0
#define LOG_WARNINGS 2 // 2^1, bit 1
#define LOG_NOTICES 4 // 2^2, bit 2
#define LOG_INCOMING 8 // 2^3, bit 3
#define LOG_OUTGOING 16 // 2^4, bit 4
#define LOG_LOOPBACK 32 // and so on...
// Only 6 flags/bits used, so a char is fine
unsigned char flags;
// initialising the flags
// note that assigning a value will clobber any other flags, so you
// should generally only use the = operator when initialising vars.
flags = LOG_ERRORS;
// sets to 1 i.e. bit 0
//initialising to multiple values with OR (|)
flags = LOG_ERRORS | LOG_WARNINGS | LOG_INCOMING;
// sets to 1 + 2 + 8 i.e. bits 0, 1 and 3
// setting one flag on, leaving the rest untouched
// OR bitmask with the current value
flags |= LOG_INCOMING;
// testing for a flag
// AND with the bitmask before testing with ==
if ((flags & LOG_WARNINGS) == LOG_WARNINGS)
...
// testing for multiple flags
// as above, OR the bitmasks
if ((flags & (LOG_INCOMING | LOG_OUTGOING))
== (LOG_INCOMING | LOG_OUTGOING))
...
// removing a flag, leaving the rest untouched
// AND with the inverse (NOT) of the bitmask
flags &= ~LOG_OUTGOING;
// toggling a flag, leaving the rest untouched
flags ^= LOG_LOOPBACK;
**
警告:不要使用相等运算符(即bitflags == bitmask) 用于测试是否设置了标志 - 该表达式仅在以下情况下才为真 该标志已设置,所有其他标志未设置。测试单个标志 你需要使用&和==:
**
if (flags == LOG_WARNINGS) //DON'T DO THIS
...
if ((flags & LOG_WARNINGS) == LOG_WARNINGS) // The right way
...
if ((flags & (LOG_INCOMING | LOG_OUTGOING)) // Test for multiple flags set
== (LOG_INCOMING | LOG_OUTGOING))
...
您还可以搜索C++ Triks
答案 1 :(得分:30)
当您想要在单个数据值中存储(并随后提取)不同数据时,使用位屏蔽是“有用的”。
我之前使用的一个示例应用程序是想象您将颜色RGB值存储在16位值中。所以看起来像这样:
RRRR RGGG GGGB BBBB
然后,您可以使用位掩码来检索颜色组件,如下所示:
const unsigned short redMask = 0xF800;
const unsigned short greenMask = 0x07E0;
const unsigned short blueMask = 0x001F;
unsigned short lightGray = 0x7BEF;
unsigned short redComponent = (lightGray & redMask) >> 11;
unsigned short greenComponent = (lightGray & greenMask) >> 5;
unsigned short blueComponent = (lightGray & blueMask);
答案 2 :(得分:3)
假设我有32位ARGB值,每通道8位。我想用另一个alpha值替换alpha分量,例如0x45
unsigned long alpha = 0x45
unsigned long pixel = 0x12345678;
pixel = ((pixel & 0x00FFFFFF) | (alpha << 24));
掩码将前8位变为0,其中旧的alpha值为。将alpha值向上移动到它将采用的最终位位置,然后将其OR进入屏蔽像素值。最终结果是0x45345678,它存储在像素中。
答案 3 :(得分:3)
如果要在一个数字中编码多层信息,则使用位掩码。
所以(假设unix文件权限)如果你想存储3级访问限制(读,写,执行),你可以通过检查相应的位来检查每个级别。
rwx
---
110
基数2中的110转换为基数10中的6。
因此,您可以轻松检查是否有人允许通过和“权限”字段读取文件并获得所需权限。
伪代码:
PERM_READ = 4
PERM_WRITE = 2
PERM_EXEC = 1
user_permissions = 6
if (user_permissions & PERM_READ == TRUE) then
// this will be reached, as 6 & 4 is true
fi
您需要理解数字和逻辑运算符的二进制表示,以理解位字段。