【问题标题】:How to store a bit-array in C++?如何在 C++ 中存储位数组?
【发布时间】:2011-12-11 09:44:23
【问题描述】:

在 C++ 中存储位数组的最佳方式是什么(没有 Boost,只有标准容器),例如表示卷分配位图?

我认为std::vector<bool> 是个好主意,但是apparently it's Evil and deprecated,那么还有更好的选择吗?

还有:

如果我在内存中有一个字节数组,我将如何将它们复制到推荐的容器中?
(我无法为vector<bool> 解决这个问题。)

【问题讨论】:

  • 你链接的文章推荐std::dynamic_bitset...
  • @GregHewgill:这似乎不在标准 C++ 中......?还是我没找到?
  • 如果你不需要 flip() 或其他特殊行为,这并不是那么邪恶。 :P
  • dynamic_bitset is in Boost.
  • vector<bool> 没有任何问题,除非您希望它像标准容器一样工作。

标签: c++ stl bitmap containers bitarray


【解决方案1】:

强大的C/С++位数组库:https://github.com/noporpoise/BitArray

【讨论】:

    【解决方案2】:

    6 年后才为后代发布此消息:就像其中一位评论者所说,我得出的结论是,使用 std::vector<bool> 作为自己的特殊类型完全可以。唯一需要注意的是不要将其视为标准的 bool 容器,因为它不是。

    【讨论】:

      【解决方案3】:

      一个 char 数组,然后用 0x1 掩码将充当一个位数组。

      例子:

      char bitarray[4]; // since 4*8 this array actually contains 32 bits
      
      char getBit(int index) {
          return (bitarray[index/8] >> 7-(index & 0x7)) & 0x1;
      }
      
      void setBit(int index, int value) {
          bitarray[index/8] = bitarray[index/8] | (value & 0x1) << 7-(index & 0x7);
      }
      

      当然,这些操作通常相对较慢,但如果内存是一个问题,这是一个不错的方法。我为此选择了 char 以减少所需的班次数量。但是,使用整数可能仍然更快。

      【讨论】:

      • 当然,我可以自己实现它,但是使用vector&lt;bool&gt; 有什么好处?
      • 你引用了一个完美的例子来说明为什么你不应该使用vector&lt;bool&gt;,这不会受到它的失败,如果你希望你也可以用 4 位块来寻址你的数组,这可以很方便一些情况。我不是 C/C++ 大师,但这似乎更正确,因为 bool 无论如何都是 C 中的黑客。
      • 是的,哇,我怎么搞砸了,感谢您指出这一点。 修复
      • 其实你应该使用CHAR_BIT或类似的东西,而不是假设字节大小是8位。
      • 除了:#if (CHAR_BIT != 8) #error.
      【解决方案4】:

      对于普通 C++,有 std::bitset.

      Bitset 与 vector(也称为 bit_vector)非常相似:它 包含一组位,并提供恒定时间访问 每一点。 bitset 和 bitset 之间有两个主要区别 向量。一、bitset的大小不能改变:bitset的 模板参数 N,它指定在 bitset,必须是整数常量。其次,bitset 不是一个序列; 事实上,它根本就不是一个 STL Container。

      马特·奥斯特恩有a nice article on its use.

      还有: 如果您的字节数组(位数组?)适合 unsigned long,那么您可以直接将其分配给 std::bitset:

      unsigned long myByteArray = 0xABCD;
      std::bitset<32> bitten( myByteArray );
      

      【讨论】:

        【解决方案5】:

        只要您的位数组大小固定,std::bitset 就可以。
        附带说明一下,还有 std::dynamic_bitset,但我不能 100% 确定它是否已成为标准。

        【讨论】:

        • 不,大小是可变的,就像在我的示例中(音量位图)。
        • @Mehrdad:那么只要您了解它与“常规”矢量 的区别,只需使用矢量。如果您选择自己实现这样的位数组,您可能会重新发明 vector,只是使用一个不那么容易混淆的名称。
        • @EugenConstantinDinca 使用vector&lt;bool&gt; 的问题是:vector&lt;bool&gt; 必须死
        • @EugenConstantinDinca 只需重命名 vector&lt;bool&gt; bitvector,或者你想要的。
        【解决方案6】:

        顺便说一句,我认为您链接到的网站上的某些观点是不正确的。在几乎每台计算机上,位的大小实际上是一个字节(与字符相同),因为计算机只能寻址一个字节而不是一个字节内的位(如果可以的话,那么您将只有八分之一的寻址空间当前拥有带字节)

        我只想为您的向量使用一个字节,因为它可以让阅读您的代码的其他人更好地了解您的应用程序的内存占用情况。

        Ram 在现代计算机中非常丰富,因此您可以使用更大的整数类型,但实际上您不能小于一个字节。

        要将数据从一个容器复制到另一个容器,首先要为容器创建一个迭代器

        vector::iterator myItr = myVector.begin()

        并使用 while 循环或 for 循环遍历向量,直到 myItr 到达 myVector.end()。

        例如

        for(vector<bool>::iterator myItr = myVector.begin(); myItr<myVector.end(); ++myItr)
        {
           otherContainer.append(*myItr);
        }
        

        【讨论】:

        • 这样复制数据的麻烦在于它的速度非常慢。不仅因为它是逐位的,而且因为实现(例如 Visual C++)有时会武断地决定在每次访问时锁定关键部分,所以它变得非常不切实际。我正在寻找一个批量移动操作(类似于items.assign(myArray, numBits),这会变得更实用,但我找不到它。
        • "_有点大小_" 拥抱?什么意思?
        猜你喜欢
        • 1970-01-01
        • 2011-06-28
        • 1970-01-01
        • 2012-06-28
        • 2011-08-20
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        • 2013-04-25
        相关资源
        最近更新 更多