@Leonardo-Tadei , no. mira:
unsigned char b0:1;
Eso dentro del struct, consume solo 1 bit. Es cierto lo que dices, la direccion minima redireccionable de memoria es de un byte. PERO, se puede trabajar individualmente bit a bit. Gracias a los struct.
En ese struct yo defino 8 lugares de un bit cada uno. Podria haber echo:
struct bits{
int b0:1;
int b1:1;
int b2:1;
int b3:1;
int b4:1;
int b5:1;
int b6:1;
int b7:1;
}
Y todo el struct seguria ocupando un byte. Puesto que tiene 8 posiciones de un bit cada uno. El :1 al lado del nombre de la variable, indica la cantidad de bits a ocupar. Podrian haber sido 5, 7 o 100 si quisiera. La definicion como int, o unsigned char, solo se hace para especificar la forma en que se almacenaran los valores dentro de ese bit. Si hubiera puesto float o double, trabajaria de forma diferente, pero seguiria ocupando un bit cada posicion del struct.
Por otro lado, si yo hubiera colocado:
struct bits{
unsigned char b0:1;
unsigned char b1:1;
unsigned char b2:1;
}
Eso no ocuparía 3 bits, como se puede esperar. Eso ocupa un byte. Por que como dices, es la minima dimension redireccionable. Por lo tanto, el tamaño de un struct, siempre deben ser multiplos de un byte. PERO, se pueden trabajar esos bytes de forma que podamos utilziarlos bit a bit.
Otra solucion que encontre, y a mi parecer mucho mejor, fue la de crear un unsigned char. Y trabajar con esta variable a travez de operaciones de corrimientos de bits. Mira:
int checkPort(unsigned short int ports, unsigned short int port){
return (ports & (1 << port));
}
void openPort(unsigned short int* ports, unsigned short int port){
if ( !checkPort(*ports,port) ){
*ports ^= (1 << port);
}
}
void closePort(unsigned short int* ports, unsigned short int port){
if (checkPort(*ports,port)){
*ports ^= (1 << port);
}
}
Con esas 3 funciones, checo el estado, abro, o cierro un puerto, respectivamente.
Gracias a todos, saludos! ;)