BOOLEAN代数NOT和DWORD - 建议修复

时间:2017-12-20 15:38:50

标签: c logic

我发现一些出错的遗留代码,设置文件属性。它看起来像这样 -

flag1 = 0x0001;
flag2 = 0x0002;

DWORD flags = flag1 | flag2;

//great - flags is 3

DWORD prevValue  = 0x0010; //say

//add our new flags to prevValue
DWORD newVal = prevValue | flags;

//newVal is 19

//but now I want to remove those flags from newVal

DWORD backToPrev = newVal & !flags;

//but according to my compiler (vs2012)
//!flags is 0, it can't do the logical NOT on the DWORD

ASSERT (backToPrev); // it's 0, should be 16

有关修复的任何建议吗?

2 个答案:

答案 0 :(得分:1)

!运算符是逻辑NOT。此运算符的结果为0或1.您想要的是按位NOT运算符~

DWORD backToPrev = newVal & ~flags;

答案 1 :(得分:0)

你可以使用|指定标志时,| =添加标志和〜删除它们。

#include <Windows.h>
#include <iostream>
using namespace std;

DWORD UpdateFlags(
    DWORD CurrentFlags,
    DWORD RemoveFlag
)
{
    return CurrentFlags & ~RemoveFlag;
}

int main()
{
    DWORD MyFlags = PROCESS_VM_OPERATION | PROCESS_VM_READ;

    MyFlags = UpdateFlags(MyFlags,
        PROCESS_VM_READ);

    getchar();
    return 0;
}

如果您这样做,您可以轻松更新标志,而无需继续使用&amp; 〜。更易于阅读。在上面的示例中,为MyFlags分配了PROCESS_VM_OPERATION和PROCESS_VM_READ标志(对我来说总共24个值),在更新标志以删除PROCESS_VM_READ之后,该值变为8,因为我们删除了PROCESS_VM_READ并且只剩下PROCESS_VM_OPERATION。

检查是否存在标志:

BOOL IsFlagPresent(
    DWORD CurrentFlags,
    DWORD TargetFlag
)
{
    return ((CurrentFlags & TargetFlag) == TargetFlag) ?
        TRUE : FALSE;
}