19

我想将位存储在数组中(如结构)。所以我可以遵循以下两种方法中的任何一种

方法 1 (AN 1)

struct BIT
{
   int data : 1
};

int main()
{
   BIT a[100];
   return 0;
}

方法 2 (AN 2)

int main()
{
    std::bitset<100> BITS;
    return 0;
}

为什么有人更喜欢 AN 2 而不是 AN 1?

4

5 回答 5

20

因为接近nr。2 实际上使用 100 位存储,加上一些非常小的(恒定)开销,而 nr. Bit1 通常每个结构使用四个字节的存储空间。通常,struct根据 C++ 标准,a 至少大一个字节。

#include <bitset>
#include <iostream>

struct Bit { int data : 1; };

int main()
{
    Bit a[100];
    std::bitset<100> b;
    std::cout << sizeof(a) << "\n";
    std::cout << sizeof(b) << "\n";
}

印刷

400
16

除此之外,bitset将您的位数组包装在具有许多有用操作的漂亮对象表示中。

于 2010-10-22T15:03:53.567 回答
7

一个好的选择取决于您将如何使用这些位。

std::bitset<N>是固定大小的。Visual C++ 10.0 不符合标准。给构造函数;一般来说,您必须提供一种解决方法。具有讽刺意味的是,这是由于微软认为是一个错误修复——int我记得他们引入了一个构造函数接受参数。

std::vector<bool>的优化方式与std::bitset. 成本:索引不直接提供引用(在 C++ 中没有对单个位的引用),而是返回一个代理对象——除非您尝试将其用作引用,否则您不会注意到它。优点:最小的存储空间,并且可以根据需要调整向量的大小。

unsigned如果您要处理少量位(实际上,32 或更少,尽管正式保证只有 16 位),简单地使用 eg也是一种选择。

最后,ALL UPPERCASE 标识符按照惯例(Microsoft 除外)为宏保留,以减少名称冲突的可能性。因此,最好不要将所有大写标识符用于宏以外的任何内容。并且始终为宏使用全部大写的标识符(这也使得它们更容易识别)。

干杯&hth.,

于 2010-10-22T15:29:28.460 回答
2

bitset 有更多的操作

于 2010-10-22T15:03:28.053 回答
0

引用cplusplus.com 在 bitset 上的页面,“该类与常规数组非常相似,但针对空间分配进行了优化”。如果您的整数是 4 个字节,则位集使用的空间少 32 倍。

即使bool bits[100]像 sbi 建议的那样做,仍然比 bitset 差,因为大多数实现都有 >= 1 字节的布尔值。

如果仅出于求知欲的原因,您想实现自己的位集,则可以使用位掩码:

typedef struct {
  unsigned char bytes[100];
} MyBitset;

bool getBit(MyBitset *bitset, int index)
{
  int whichByte = index / 8; 
  return bitset->bytes[whichByte] && (1 << (index = % 8));
}

bool setBit(MyBitset *bitset, int index, bool newVal)
{
  int whichByte = index / 8;

  if (newVal)
  {
    bitset->bytes[whichByte] |= (1 << (index = % 8));
  }
  else
  {
    bitset->bytes[whichByte] &= ~(1 << (index = % 8));
  }
}

(对不起,顺便说一句,使用结构而不是类。我正在考虑直接使用 C 语言,因为我正处于学校低级作业的中间。显然,使用类的两个巨大好处是运算符重载和拥有可变大小数组的能力。)

于 2010-10-22T15:06:11.893 回答
0

方法 1 很可能被编译为一个 4 字节整数数组,每个整数的一位将用于存储您的数据。从理论上讲,智能编译器可以优化这一点,但我不会指望它。

你有不想使用的理由std::bitset吗?

于 2010-10-22T15:03:15.707 回答