在 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
。如果需要 0
和 1
:
,请使用 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
我正在开发只有 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
。如果需要 0
和 1
:
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
orfalse
is stored into a bit-field of typebool
of any size (including a one bit bit-field), the originalbool
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