我正在学习位标志并使用逐位运算符手动创建位字段。然后我遇到了bitsets,似乎是一种更简单,更清晰的存储位字段的方法。我理解使用位字段的价值,尽量减少内存使用量。不过,在测试了sizeof(bitset)之后,我很难理解这是一种更好的方法。
考虑:
#include <bitset>
#include <iostream>
int main ()
{
// Using Bit Set, Size = 8 Bytes
const unsigned int i1 = 0;
const unsigned int i2 = 1;
std::bitset<8> mySet(0);
mySet.set(i1);
mySet.set(i2);
std::cout << sizeof(mySet) << std::endl;
// Manually managing bit flags
const unsigned char t1 = 1 << 0;
const unsigned char t2 = 1 << 1;
unsigned char bitField = 0;
bitField |= t1 | t2;
std::cout << sizeof(bitField) << std::endl;
return 0;
}
输出结果为:
mySet是8个字节。 bitField是1个字节。
如果需要最少的内存使用,我不应该使用std :: bitset吗?
答案 0 :(得分:1)
为了尽可能降低内存占用率,您不应该使用std::bitset
。它可能需要比简单内置类型(例如等效有效大小的char
或int
)更多的内存。因此,它可能有内存开销,但多少将取决于实现。
std::bitset
的一个主要优点是它可以使您摆脱各种类型的硬件相关实现。理论上,硬件可以使用任何类型的任何表示,只要它满足C ++标准中的某些要求即可。因此,当你依赖unsigned char t1 = 1
在内存中00000001
时,实际上并没有保证。但是如果你创建一个bitset并正确地初始化它,它就不会给你带来任何令人讨厌的惊喜。
关于bitfiddling的旁注:考虑到以这种方式摆弄比特的陷阱,你能否真正证明这种容易出错的方法,而不是使用std::bitset
甚至类似int
和{{1}的类型}?除非您的资源受到极大的限制(例如MCU / DSP编程),否则我认为您无法做到。
那些玩位的人会被咬,而那些玩字节的玩家将会被击败。
顺便说一下,使用按位运算符声明和操作的bool
是一个位字段,但它不是位字段的C ++语言概念,如下所示:
char bitField
简而言之,它是一种数据结构,其数据成员被细分为单独的变量。在这种情况下,(大概)8位的struct BitField{
unsigned char flag1 : 1, flag2 : 1, flag3 : 1;
}
用于创建三个1位变量(unsigned char
,flag1
和flag2
)。它被明确细分,但在一天结束时,这只是编译器/语言辅助的比特摆弄类似于你上面所做的。你可以read more about bit fields here。