在1字节内存储8个逻辑真/假值?

时间:2015-04-24 19:16:36

标签: c++ bit-fields

我正在使用仅有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
}

是什么给出了?

4 个答案:

答案 0 :(得分:113)

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

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

答案 1 :(得分:13)

谨慎之处 - 标准并没有真正实施位域的实现方案。不能保证Bits将是1个字节,并且假设它完全可能更大。

在实践中,实际的实现通常遵循明显的逻辑,它几乎总是&#34;是1字节大小,但同样,没有要求保证。如果您想确定,可以do it manually

BTW -1仍为true,但-1 != true

答案 2 :(得分:3)

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

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

  

如果值truefalse存储在任意大小的bool类型的位字段中(包括一位位字段),则原始bool值和比特字段的值应相等。

是的,std::uint8_t将完成这项工作,但您也可以使用最合适的工作。你不需要像std::cout << (int)b.b0;的演员表这样的东西。

答案 3 :(得分:0)

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

请记住,信号只是对比特的解释,-1或1只是&#39; print&#39;序列化器解释&#34;变量类型&#34;,因为它是&#34;显示&#34;通过编译器来cout函数(查看运算符重载),该位是相同的,它的值也是(开/关) - 因为你只有1位。

不要关心这一点,但明确是一个好习惯,所以更喜欢用unsigned声明你的变量,它指示编译器在设置或获取类似于序列化器的值时安装正确的代码&#34;打印&#34; (COUT)。

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