按位操作是否会帮助我序列化一些bool?

时间:2011-02-01 08:31:48

标签: c++ bit-manipulation binaryfiles

我不习惯二进制文件,而我正试图抓住它。我设法存储了一些整数和unsigned char,并且没有太多的痛苦就读了它们。现在,当我试图保存一些布尔值时,我看到我的每个bool在我的文件中只占用了1个八位字节,这似乎是合乎逻辑的,因为一个单独的bool存储在一个字符大小的数据中(如果我错了,请纠正我) !)。

但是因为我将要有3或4个bool来序列化,我认为这样存放它们是浪费:00000001 00000001 00000000,例如,当我可以有00000110时。我想要得到这个我应该使用按位操作,但我对它们不是很好......所以有人可以告诉我:

  1. 如何使用按位操作在一个八位字节中存储多达8个bool?
  2. 如何使用按位操作从单个八位字节中为(最多8个bool)提供适当的值?
  3. (而且,奖金问题,是否有人可以推荐一个简单的,非数学导向的思维,如我的,位操作教程,如果存在的话?我发现的一切我理解但无法付诸实践......)
  4. 我正在使用C ++,但我猜大多数C语法语言都会使用相同类型的操作。

6 个答案:

答案 0 :(得分:2)

简单的方法是使用std :: bitset,它允许您使用索引来访问各个位(bools),然后将结果值作为整数获取。它也允许相反。

int main() {
  std::bitset<8> s;
  s[1] = s[2] = true;  // 0b_0000_0110
  cout << s.to_ulong() << '\n';
}

答案 1 :(得分:2)

以一个字节存储bool:

bool flag; // value to store
unsigned char b = 0; // all false
int position; // ranges from 0..7
b = b | (flag << position);

要读回来:

flag = (b & (1 << position));

答案 2 :(得分:1)

没有包装花哨的模板/预处理器机器:

  • var 中设置第3位:
    var |= (1 << 3)
  • var 中设置位 n
    var |= (1 << n)
  • 清除 var 中的位 n
    var &= ~(1 << n)
  • var 中测试位 n :( !!确保结果为0或1)
    !!(var & (1 << n))

答案 3 :(得分:1)

请按顺序阅读此内容。

  1. http://www.cprogramming.com/tutorial/bitwise_operators.html

  2. http://www-graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching

  3. 有些人会想到第二个链接太硬了,但是一旦你掌握了简单的操作,它就会派上用场。

答案 4 :(得分:1)

基本的东西第一:

  • 唯一表示错误的位组合是00000000所有其他意味着是真的,即:00001000,01010101
  • 00000000 = 0(十进制),00000001 = 2 ^ 0,00000010 = 2 ^ 1,00000100 = 2 ^ 2,.... ,10000000 = 2 ^ 7
  • 操作数(&amp;&amp;,||)和(&amp;,|)之间存在很大差异,第一个给出两个数字之间逻辑运算的结果,例如:

    <00> 00000000&amp;&amp; 00000000 = false,

    01010101&amp;&amp; 10101010 = true

    00001100 || 00000000 = true,

    00000000 || 00000000 =假

    第二对进行逐位运算(数字的每个位之间的逻辑运算):

    <00> 00000000&amp; 00000000 = 00000000 = false

    00001111&amp; 11110000 = 00000000 = false

    01010101&amp; 10101001 = 00000001 = true

    00001111 | 11110000 = 11111111 = true

    00001100 | 00000011 = 00001111 = true


要使用它并使用这些位,你只需要了解一些基本技巧:

  • 要将位设置为1,请执行操作|一个八位位组,其中一个位于该位置,而其余位置则为ceros。

例如:我们希望八位位组A的第一位为1:A | 00000001

  • 要将某位设置为0,您可以进行操作&amp;一个八位字节,其中该位置为0,其余位置为。

例如:我们希望八位字节A的最后一位为0:A&amp; 01111111

  • 要获得保持位的布尔值,您可以进行操作&amp;一个八位位组,其中一个位于该位置,而其余位置则为ceros。

例如:我们希望看到八位字节A的第三位的值,我们制作:A&amp; 00000100,如果A是XXXXX1XX,我们得到00000100 = true,如果A是XXXXX0XX我们get 00000000 = false;

答案 5 :(得分:0)

您始终可以序列化位域。类似的东西:

struct bools 
{
    bool a:1;
    bool b:1;
    bool c:1;
    bool d:1;
};

的尺寸为1