c++位运算运用之掩码(BitMask)

c++位运算运用之位掩码(BitMask)

场景:假如我想写一个动画小人,某个接口仅仅传int型就可以同时控制小人抬右手、抬左脚、闭眼睛,或者同时抬右手,抬左脚、睁眼睛。这儿其实就是一些动作的组合,可以把不同动作对应到int的每一个位上,int 占4个字节,每个字节8位,共32位,每一个位来表示一种动作,那么可以同时组合32个动作。
内存分布就像这样:
11111111 11111111 11111111 11111111
这样一个int 的值就是INT_MAX
实现:
1.定义枚举表示各种动作:

enum Animation {
    None = 0,                 // 0x0
    ShutEye = 1 << 1,         // 0x1
    OpenEye = 1 << 2,         // 0x10
    RaiseRightLeg = 1 << 3,   // 0x100
    RaiseLeftLeg = 1 << 4,    // 0x1000
    RaiseRightHand = 1 << 5,  // 0x10000
    raiseLeftHand =1 << 6     // 0x100000
};

1.定义方法实现不同动作组合:

void Dance(int animation)
{
    switch (animation)
    {
    case (ShutEye | RaiseLeftLeg | RaiseRightHand):
        std::cout << "小人 举右手 、 抬左腿、 闭眼" << std::endl;
        break;
    case (OpenEye | RaiseLeftLeg | RaiseRightHand):
        std::cout << "小人 举右手 、 抬左腿、 睁眼" << std::endl;
        break;
    default:
        break;
    }
}

int main()
{
    Dance(ShutEye | RaiseLeftLeg | RaiseRightHand);
    std::cout << "Hello World!\n";
}

哈哈哈,脑补一下画面就好,为了说明问题就使用简单的文字说明,如果真得有人个小人在画面上起舞,那将输出行换成相应的实现逻辑即可。

掩码的常用操作:
1.组合不同的标志位,直接使用位运算或(|)起来,就如我想让小人抬左脚和抬右脚 :
RaiseLeftLeg | RaiseRightLeg
c++位运算运用之掩码(BitMask)_第1张图片
2.去掉flag中的某一项,就比如我们永远都不想让小人抬起右脚。这时可以分两步走,第一步把要去掉的标志位取反。第二步在和目标标志位与(&)起来。

c++位运算运用之掩码(BitMask)_第2张图片

那么现在我只想小人的眼睛永远是睁开的,闭着就不美了,怎么办呢? 只需去掉标志ShutEye即可

void Dance(int animation)
{
    int noShutEye = ~Animation::ShutEye; // 1. 取反
    animation = animation & noShutEye;   // 2. 与目标值&起来
    // 将上面合并为一行
    // animation = animation & (~Animation::ShutEye);
    switch (animation)
    {
    case (ShutEye | RaiseLeftLeg | RaiseRightHand):
        std::cout << "小人 举右手 、 抬左腿、 闭眼" << std::endl;
        break;
    case (OpenEye | RaiseLeftLeg | RaiseRightHand):
        std::cout << "小人 举右手 、 抬左腿、 睁眼" << std::endl;
        break;
    default:
        break;
    }
}

总结:
位掩码在编码中还是比较常见的,其中要注意的一点就是一个int 仅仅可以表示32种标志,因为只有32位二进制,并且用1标识哪一个位代表什么flag。如果还需要多余32中可以挑一个更大的类型,或者直接使用自定义类,实现与或取反(& | ~)三种操作符,那么即可扩展到好多标志。还有就是去掉标志位时,一定要先取反在与。得呢,今也差不多了,早早就起来撸文章,搞得睡眼朦胧的呢,这可爱的床,我来了。

你可能感兴趣的:(南小馆)