【问题标题】:C++ bool array as bitfield?C ++ bool数组作为位域?
【发布时间】:2010-12-18 20:20:22
【问题描述】:

假设我需要在一个结构中存储 8 个布尔值,但我只想一起使用 1 个字节,那么我可以这样做:

struct myStruct {
    bool b1:1;
    bool b2:1;
    bool b3:1;
    bool b4:1;
    bool b5:1;
    bool b6:1;
    bool b7:1;
    bool b8:1;
};

有了这个我可以做类似的事情

myStruct asdf;
asdf.b3=true;
asdf.b4=false;
if(asdf.b1)
    ...

到目前为止这是正确的吗? (实际上我不知道,我以前从未使用过位域)

好的 - 但是是否也可以创建一个包含 8 个布尔值的静态数组,这样它们将只使用 8 位,但我仍然可以通过索引来寻址它们?

类似

struct myStruct {
public:
    bool b[8]:8;
};

也许? (有了这个,我得到一个错误 C2033)

感谢您的帮助!

【问题讨论】:

    标签: c++ struct boolean bit-fields


    【解决方案1】:

    我建议使用std::bitset 这样您就可以简单地声明:

    std::bitset<8> asdf;
    

    并与 [] 一起使用。

    asdf[0] = true;
    asdf[3] = false;
    

    【讨论】:

    • 作为 T.E.D.指出,当考虑对齐问题时,任何数据结构都很有可能占用 32 位。
    • 在另一个问题中有一些很好的链接可以解释对齐问题:stackoverflow.com/questions/381244/purpose-of-memory-alignment
    • Bitsets 是 32 字节是有原因的,它在所有情况下都快得多。除了可能存在大量位集的情况,但我会制作一个更大的位集?
    【解决方案2】:

    您不想使用byte 数据类型同时保存所有内容吗?然后你只需要使用逻辑ANDs 和ORs 来获取/放入东西。不需要struct

    【讨论】:

      【解决方案3】:

      出于各种原因,我认为这不是一个好主意 - 您基本上是在尝试复制 vector&lt;bool&gt; 的行为,这已被证明是 not a good idea。如果您只是为了节省内存而尝试这样做,我不会打扰。访问各种布尔值并从位字段中提取它们的开销可能比您节省的少量内存要高得多,除非您受到内存限制的极大限制。

      要回答你的直接问题,如果你想做布尔/位域的事情,你必须使用你的第一种方法。

      通常,位域/位旋转方法的合法且被接受的用途是当您必须处理硬件寄存器并尝试对硬件寄存器进行建模或在使其看起来像内存位置并叠加后实际访问硬件寄存器时寄存器上的位域结构。

      【讨论】:

      • 嘿!是的,它与记忆有关。问题是,我必须在堆上创建许多这些对象,并且它接缝我的结构的大小会线性地影响我的应用程序的性能。将其从 64 字节减少到 36 字节,增加了一倍多。所以现在我正在寻找进一步缩小尺寸的方法
      【解决方案4】:

      您也许可以让您的编译器做您想做的事,但遗憾的是这不是必需的。例如,即使是接受上述内容的好编译器也可能最终为您的 myStruct 对象分配一个完整的 32 位字。

      如果您可以选择,并且希望对您的类型以及它们的对齐和分配方式进行这种级别的控制,您可能应该考虑使用 Ada。例如,以下在 Ada 中工作得很好:

      type Bit_Set is array (1..8) of Boolean;
      for Bit_Set'size use 8;
      
      High_Mask : constant Bit_Set := (1..7 => false, 8 => true);
      

      ...您现在有了一个单字节位掩码,以及可以按位使用的运算符“and”、“or”、“xor”等。

      【讨论】:

      • +1 用于提出对齐问题; -1 用于建议更改编程语言。净 0 :)
      • 很公平。我只是对 C 的局限性感到非常沮丧,我不禁要提到它们不是必需的。
      • 问题 title 专门要求 C++ 解决方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多