What is the": "(colon) for in the statement of a member of a structure?
I saw this:
typedef struct {
unsigned char a : 1;
unsigned char b : 7;
} Tipo;
What does this statement mean? What is this 1 and 7?
1 answers
Let's run this code to better understand:
#include <stdio.h>
typedef struct {
unsigned char a : 1;
unsigned char b : 7;
} Tipo;
int main(void) {
Tipo x = { .a = 1, .b = 64 };
printf("%d e %d\n", x.a, x.b);
printf("%zd\n", sizeof(Tipo));
}
See working on ideone. E no repl.it. also I put on GitHub for future reference .
Try to put a value greater than 1 on the member a
. It doesn't work, it can only be 0 or 1. Have you picked up why?
In the second impression we see that the size of this structure is 1 byte. And now, did you kill?
The colon is used when the structure is used to assemble a string of bits and each member is called the bit field. So what comes after :
is the amount of bits that that member contains. So a
can only have 0 or 1. It only has 1 bit. The same goes if you try to put more than 127 in b
that only has 7 bits.
Ideally these structures should have a total size multiple of 8 to fit with a byte, but if it does not, a alignment will occur according to the rules of the compiler.
Possible member types are specified as _Bool
, signed int
, unsigned int
and others specified by the compiler, which is what was used. It is usually better to use types with universally defined size. So it's better a int32_t
than a int
.
It is very common for this type of structure to be within a larger structure with other members.
It is also very common to use with union
. So you can access a union member as a data single and the other member of the Union as a bit structure.
#include <stdio.h>
typedef union {
char valor;
struct {
unsigned char a : 1;
unsigned char b : 1;
unsigned char c : 1;
unsigned char d : 1;
unsigned char e : 1;
unsigned char f : 1;
unsigned char g : 1;
unsigned char : 1;
} bits;
} Tipo;
int main(void) {
Tipo x = { .valor = 87 };
printf("%d %d %d %d %d %d %d", x.bits.a, x.bits.b, x.bits.c, x.bits.d, x.bits.e, x.bits.f, x.bits.g);
}
See working on ideone. E no repl.it. also I put on GitHub for future reference .
Note that I showed another point. You are not required to identify all the bits. Of course, not putting a name on some bit, or set of bits, you will not be able to access its value in a direct and named way.