You should do like this:
#define BIT_MASK 0x20
unsigned char some_data;
some_data |= BIT_MASK; /* set bit */
some_data &= ~BIT_MASK; /* clear bit */
Which is the same thing as
some_data = some_data | BIT_MASK;
some_data = some_data & ~BIT_MASK;
The above operators are called the "bit-wise" operators. This code works on all C/C++ compilers in the world.
A poor way to do the same is like this:
unsigned int some_data : 1;
data.some_data = 1; /* set bit */
data.some_data = 0; /* clear bit */
This code will compile on all compilers, but it is poor programming. The above is called "bit fields", and bit fields are very
poorly defined by the standard. The only allowed type is int, you cannot use them with any other type.
And you shouldn't use them, but know that they exist. Sadly, they are very commonly used by so-called programmers in embedded systems.
You shouldn't use them because of the following reasons (advanced topic, beginners may stop reading here
- You don't know if the first bit in the struct is msb or lsb.
- You don't know how the bits are stored in memory.
- The code will be little/big endian dependant.
- You don't know whether "int" will be treated as signed or unsigned.
- You don't know if arrays of bit fields will work or not.
- Padding bytes are allowed inside bit fields.
- There is a risk that beginner programmers use other types than int for bit fields, which is undefined behavior in the standard and will cause the code to behave completely randomly.