在 1 个字节内存储 8 个逻辑 true/false 值?

Storing 8 logical true/false values inside 1 byte?

我正在开发只有 2KB SRAM 的微控制器,迫切需要节省一些内存。试图找出如何使用位域将 8 个 0/1 值放入单个字节,但无法完全解决。

struct Bits
{
    int8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};

int main(){
    Bits b;
    b.b0 = 0;
    b.b1 = 1;

    cout << (int)b.b0; // outputs 0, correct
    cout << (int)b.b1; // outputs -1, should be outputting 1
}

什么给了?

您所有的位域成员都是带符号的 1 位整数。在二进制补码系统中,这意味着它们只能表示 0-1。如果需要 01:

,请使用 uint8_t
struct Bits
{
    uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};

请注意 - 该标准并未真正强制执行位域的实现方案。不能保证 Bits 将是 1 个字节,并且假设它完全有可能更大。

然而在实践中,实际的实现通常遵循明显的逻辑,"almost always" 大小为 1 个字节,但同样,没有保证它的要求。以防万一你想确定,你可以 do it manually.

顺便说一句 -1 仍然是 true 但它 -1 != true

如前所述,这些变量仅包含一个符号位,因此唯一可用的值是 0-1

更适合这些位域的类型是 bool。 C++14 §9.6/4:

If the value true or false is stored into a bit-field of type bool of any size (including a one bit bit-field), the original bool value and the value of the bit-field shall compare equal.

是的,std::uint8_t 可以胜任,但您不妨使用最合适的。你不需要像 std::cout << (int)b.b0;.

这样的演员表

有符号和无符号整数就是答案。

请记住,信号只是对位的解释,-1 或 1 只是 'print' 序列化器解释 "variable type",因为它是 "revealed" 来计算函数(看编译器的运算符重载),位是相同的,它的值也是 (on/off) - 因为你只有 1 位。

不关心这个,但是明确是一个好习惯,所以更喜欢用无符号声明你的变量,它指示编译器在你设置或获取序列化程序的值时安装正确的代码,比如"print" (cout).

"COUT" 运算符超载: "cout" 通过一系列函数工作,参数重载指示编译器调用哪个函数。因此,有两个函数,一个接收无符号的,另一个接收有符号的,因此它们可以不同地解释相同的数据,并且您可以更改它,指示编译器使用强制转换调用另一个。参见 cout << myclass