I am trying to implement boolean data type in C. Basically, I am working with sets.
The following code can be used to access each bit but I am unsure whether I can represent sets using this method.
Can somebody clarify this for me?
struct SET {
unsigned int b0 :1; // bit 0 single bit
unsigned int b1 :1; // bit 1 single bit
unsigned int b2 :1;
unsigned int b3 :1;
};
I can define two structures s1 and s2.. and I will be able to access each bit of these structures (treated as boolean strings).
I will have to perform set operations like UNION, INTERSECTION and MEMBERSHIP. Is this even possible in C?
Note: I cannot use Java, only C.
7
C doesn’t have any built-in set operations, but if your sets can be represented by a bitset with fewer than 64 bits (32 in older implementations), then you can use bit-operations to simulate the set operations (using AND (&
) for set intersection and OR (|
) for set union).
Your structure is easy for testing membership (just see if the corresponding member is not 0
), but not that easy for operations on multiple bits. That is easier on an unsigned number. To get the best of both worlds, use a union:
union SET {
struct items {
unsigned int a: 1;
unsigned int b: 1;
unsigned int c: 1;
unsigned int d: 1;
unsigned int e: 1;
unsigned int f: 1;
unsigned int g: 1;
unsigned int h: 1;
};
uint8_t bits; // As we only have 8 items for our set
};
You do the bit operations on the bits
member, and the membership tests/sets on the items.[abcdefgh]
members.
3
In memory these can be accessed as flags, so you can use standard flag operations,
struct SET {
unsigned int b0 :1; // bit 0 single bit
unsigned int b1 :1; // bit 1 single bit
unsigned int b2 :1;
unsigned int b3 :1;
};
struct SETFlag {
union {
SET set;
unsigned int set_as_flag;
};
};
/* example use */
SETFlag a, b, c;
/* initialize */
c.set_as_flag = a.set_as_flag | b.set_as_flag; /* union */
/* c.set, now you can use set */
This assumes you have <= 32 members for a 4 byte int, you could ensure its value is correct,
_Static_assert(sizeof(((struct SETFlag *)0)->set) <=
sizeof(((struct SETFlag *)0)->set_as_flag),
"SETFlag.set_as_flag is too small!");
However all this begs the question, why not just use flags.
1