c++ - tipos - variable double
¿Almacenar 8 valores lógicos verdadero/falso dentro de 1 byte? (4)
Estoy trabajando en un microcontrolador con solo 2 KB de SRAM y necesito desesperadamente conservar algo de memoria.
Tratando de averiguar cómo puedo poner los valores de
1
0/1 en un solo byte usando un campo de bits, pero no puedo resolverlo.
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
}
¿Lo que da?
Como advertencia, el estándar realmente no impone un esquema de implementación para bitfields.
No hay garantía de que los
Bits
sean de 1 byte, e hipotéticamente es completamente posible que sea más grande.
Sin embargo, en la práctica, las implementaciones reales generalmente siguen la lógica obvia y "casi siempre" tendrá un tamaño de 1 byte, pero nuevamente, no hay ningún requisito de que esté garantizado. En caso de que quiera estar seguro, puede hacerlo manualmente .
Por cierto
-1
sigue siendo
true
pero
-1 != true
Como se señaló, estas variables consisten solo en un bit de signo, por lo que los únicos valores disponibles son
0
y
-1
.
Un tipo más apropiado para estos campos de bits sería
bool
.
C ++ 14 §9.6 / 4:
Si el valor
true
ofalse
se almacena en un campo de bits de tipobool
de cualquier tamaño (incluido un campo de bits de un bit), el valor debool
original y el valor del campo de bits se compararán igual.
Sí,
std::uint8_t
hará el trabajo, pero también podrías usar el mejor ajuste.
No necesitará cosas como el reparto para
std::cout << (int)b.b0;
.
Los enteros con y sin signo son la respuesta.
Tenga en cuenta que la señalización es solo una interpretación de bits, -1 o 1 es solo el serializador ''print'' que interpreta el "tipo variable", como fue "revelado" a las funciones cout (mire sobrecarga del operador) por compilador, el bit es igual, su valor también (activar / desactivar), ya que solo tiene 1 bit.
No me importa eso, pero es una buena práctica ser explícito, así que prefiera declarar su variable con unsigned, le indica al compilador que monte un código apropiado cuando configura u obtiene el valor en un serializador como "print" (cout )
SOBRECARGA DEL OPERADOR "COUT": "cout" funciona a través de una serie de funciones que la sobrecarga de parámetros indica al compilador a qué función llamar. Por lo tanto, hay dos funciones, una recibe una sin firmar y otra firmada, por lo que pueden interpretar los mismos datos de manera diferente, y usted puede cambiarlos, indicando al compilador que llame a otro usando cast. Ver cout << myclass
Todos sus miembros de bitfield son enteros de 1 bit con signo.
En un sistema de complemento a dos, eso significa que solo pueden representar
0
o
-1
.
Use
uint8_t
si desea
0
y
1
:
struct Bits
{
uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};