0

我正在学习位标志并使用按位运算符手动创建位字段。然后我遇到了位集,这似乎是一种更简单、更清洁的存储位字段的方法。我理解使用位字段的价值,以尽量减少内存使用。但是,在测试 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 个字节。位域为 1 个字节。

如果需要最少的内存使用量,我不应该使用 std::bitset 吗?

4

1 回答 1

1

为了尽可能减少内存占用,您不应该使用std::bitset. 它可能需要比普通内置类型charint等效有效大小更多的内存。因此,它可能有内存开销,但多少将取决于实现。

一个主要优点std::bitset是它使您从各种类型的硬件相关实现中解放出来。理论上,硬件可以对任何类型使用任何表示,只要它满足 C++ 标准中的某些要求。因此,当您依赖内存时,实际上并不能保证这一点unsigned char t1 = 100000001但是,如果您创建一个 bitset 并正确初始化它,它不会给您带来任何令人讨厌的惊喜。

关于位摆弄的旁注:考虑到以这种方式摆弄位的陷阱,您真的可以证明这种容易出错的方法而不是使用std::bitset甚至像intand这样的类型bool吗?除非您资源极度受限(例如 MCU / DSP 编程),否则我认为您做不到。

玩比特的会被咬,玩字节的会被咬。


顺便说一句,char bitField您使用按位运算符声明和操作的是一个位域,但它不是 C++ 语言的位域概念,如下所示:

struct BitField{
    unsigned char flag1 : 1, flag2 : 1, flag3 : 1;
}

松散地说,它是一种数据结构,其数据成员被细分为单独的变量。在这种情况下unsigned char,(大概)8 位用于创建三个 1 位变量(flag1flag2flag3。它被明确细分,但归根结底,这只是编译器/语言辅助的位摆弄,类似于您在上面所做的。您可以在此处阅读有关位域的更多信息

于 2018-05-25T21:23:41.333 回答