位域与位集

发布于 2024-09-28 18:43:31 字数 302 浏览 5 评论 0原文

我想将位存储在数组(如结构)中。因此,我可以采用以下两种方法之一

方法 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?

I want to store bits in an array (like structure). So I can follow either of the following two approaches

Approach number 1 (AN 1)

struct BIT
{
   int data : 1
};

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

Approach number 2 (AN 2)

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

Why would someone prefer AN 2 over AN 1?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

美人骨 2024-10-05 18:43:31

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

#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 将位数组包装在一个漂亮的对象表示中有许多有用的操作。

Because approach nr. 2 actually uses 100 bits of storage, plus some very minor (constant) overhead, while nr. 1 typically uses four bytes of storage per Bit structure. In general, a struct is at least one byte large per the C++ standard.

#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";
}

prints

400
16

Apart from this, bitset wraps your bit array in a nice object representation with many useful operations.

枯寂 2024-10-05 18:43:31

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

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

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

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

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

干杯&呵呵,,

A good choice depends on how you're going to use the bits.

std::bitset<N> is of fixed size. Visual C++ 10.0 is non-conforming wrt. to constructors; in general you have to provide a workaround. This was, ironically, due to what Microsoft thought was a bug-fix -- they introduced a constructor taking int argument, as I recall.

std::vector<bool> is optimized in much the same way as std::bitset. Cost: indexing doesn't directly provide a reference (there are no references to individual bits in C++), but instead returns a proxy object -- which isn't something you notice until you try to use it as a reference. Advantage: minimal storage, and the vector can be resized as required.

Simply using e.g. unsigned is also an option, if you're going to deal with a small number of bits (in practice, 32 or less, although the formal guarantee is just 16 bits).

Finally, ALL UPPERCASE identifiers are by convention (except Microsoft) reserved for macros, in order to reduce the probability of name collisions. It's therefore a good idea to not use ALL UPPERCASE identifiers for anything else than macros. And to always use ALL UPPERCASE identifiers for macros (this also makes it easier to recognize them).

Cheers & hth.,

2024-10-05 18:43:31

bitset有更多操作

bitset has more operations

誰認得朕 2024-10-05 18:43:31

方法 1 最有可能被编译为 4 字节整数数组,并且每个整数的一位将用于存储数据。理论上,智能编译器可以对此进行优化,但我不会指望它。

您是否有理由不想使用 std::bitset

Approach number 1 will most likely be compiled as an array of 4-byte integers, and one bit of each will be used to store your data. Theoretically a smart compiler could optimize this, but I wouldn't count on it.

Is there a reason you don't want to use std::bitset?

一抹淡然 2024-10-05 18:43:31

引用 cplusplus.com 关于 bitset 的页面,“该类与常规的数组,但优化空间分配”。如果您的 int 为 4 个字节,则位集使用的空间将减少 32 倍。

即使按照 sbi 的建议执行 bool bits[100] ,仍然比 bitset 更糟糕,因为大多数实现都具有 >= 1 字节的 bool。

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

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 进行思考,因为我显然,使用类的两个巨大好处是运算符重载和拥有可变大小数组的能力。)

To quote cplusplus.com's page on bitset, "The class is very similar to a regular array, but optimizing for space allocation". If your ints are 4 bytes, a bitset uses 32 times less space.

Even doing bool bits[100], as sbi suggested, is still worse than bitset, because most implementations have >= 1-byte bools.

If, for reasons of intellectual curiosity only, you wanted to implement your own bitset, you could do so using bit masks:

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));
  }
}

(Sorry for using a struct instead of a class by the way. I'm thinking in straight C because I'm in the middle of a low-level assignment for school. Obviously two huge benefits of using a class are operator overloading and the ability to have a variable-sized array.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文