在C中如何“反转”此运算符| =

时间:2011-07-13 14:13:50

标签: c bit-manipulation

我是C语言编程的新手,我有以下情况,我知道需要做什么,我只是不确定正确的方法。我会尽量保持简单,如果我没有提供足够的信息,请告诉我。

这行有一个.h文件:

#define NS_CONN_ENTITYTOOLARGE    0x2000

然后在C代码中我们设置了以下标志:

connPtr->flags |= NS_CONN_ENTITYTOOLARGE;

然后在这个测试中:

if (connPtr->flags & NS_CONN_ENTITYTOOLARGE) {
}

现在我想要做的是基本上“撤消”标志NS_CONN_ENTITYTOOLARGE。经过一些谷歌搜索,我发现|=是一个“按位OR”,但在得知之后我感觉不那么开明。我需要做一个按位XOR,一个NOT还是什么?

以下是我可以在头文件中找到的标志的所有可能值。

#define NS_CONN_CLOSED        0x1
#define NS_CONN_SKIPHDRS      0x2
#define NS_CONN_SKIPBODY      0x4
#define NS_CONN_READHDRS      0x8
#define NS_CONN_SENTHDRS      0x10
#define NS_CONN_KEEPALIVE     0x20
#define NS_CONN_WRITE_ENCODED     0x40
#define NS_CONN_FILECONTENT       0x80
#define NS_CONN_RUNNING           0x100
#define NS_CONN_OVERFLOW      0x200
#define NS_CONN_TIMEOUT           0x400
#define NS_CONN_GZIP          0x800
#define NS_CONN_CHUNK         0x1000
#define NS_CONN_ENTITYTOOLARGE    0x2000

7 个答案:

答案 0 :(得分:13)

您无法将OR反转为之前的值。信息丢失了,请考虑这个真值表:

A|B|OR
------
0|0|0
0|1|1
1|0|1
1|1|1

正如您所看到的,信息丢失是因为当A为0或1时没有明确的值。

您想知道的是如何删除标记。这可以通过AND与标志的倒数来完成:

connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE; 

答案 1 :(得分:8)

connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE;

这并不完全“撤消”|=,因为它可能是NS_CONN_ENTITYTOOLARGE中部分或全部位的无操作,如果它们已经在变量中。在这些情况下,这些位也将被清除,无论它们是否在那里。

答案 2 :(得分:3)

异或:

connPtr->flags ^= NS_CONN_ENTITYTOOLARGE

当然,这正在考虑(比如说):

  1. flags = 01001101
  2. NS_CONN = 00010000
  3. 示例:

    flags |= NS_CONN;
    
    OR 01001101
       00010000
    ------------
       01011101
    

    然后:

    flags ^= NS_CONN
    
    XOR 01011101
        00010000
    -------------
        01001101 (== original flags)
    

答案 3 :(得分:2)

你需要做一个按位和标志的倒数:

connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE;

~NS_CONN_ENTITYTOOLARGE的每一位都是1,除了它代表的位 因此,该值的每个其他位都会AND1一起编辑,这不会做任何事情。

答案 4 :(得分:1)

你无法撤消它本身 - 在操作之后,connPtr->flags将在NS_CONN_ENTITYTOOLARGE有1位(在这种情况下只有一个位置)的所有位置都有1位,除非你实际存储了connPtr->flags的原始值,否则无法知道原始位值是什么。如果您有兴趣将位位置更改为0(可能不是原始位值),您可以按照此处的其他帖子进行操作。

答案 5 :(得分:0)

要删除标记,请使用AND:

connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE;

这将占用标志中的所有位,但 NS_CONN_ENTITYTOOLARGE除外。

答案 6 :(得分:0)

您希望connPtr->flags &= ~NS_CONN_ENTITYTOOLARGE使用&为AND且~不是。