This is simple custom data type that allows you to manipulate bits, bytes, or whatever comes into a 32 bit integer. It uses unions for this purpose because all data types within a union share the same memory. This can be very useful for low level purposes such as setting flags without using masking. Here […]
CodeGuru content and product recommendations are
editorially independent. We may make money when you click on links
to our partners.
Learn More
This is simple custom data type that allows you to manipulate bits, bytes, or whatever comes into a 32 bit integer. It uses unions for this purpose because all data types within a union share the same memory. This can be very useful for low level purposes such as setting flags without using masking.
Here is the custom type union comprising one DWORD.
typedef struct _BITS8
{
unsigned char bit0 : 1;
unsigned char bit1 : 1;
unsigned char bit2 : 1;
unsigned char bit3 : 1;
unsigned char bit4 : 1;
unsigned char bit5 : 1;
unsigned char bit6 : 1;
unsigned char bit7 : 1;
}BITS8;
typedef struct _QUATERS
{
unsigned char quater0 : 4;
unsigned char quater1 : 4;
}QUATERS;
typedef union _BITSQUATERS
{
BITS8 bits;
QUATERS quaters;
unsigned char byte;
}BITSQUATERS;
typedef union _BITS32
{
BITSQUATERS byte[4];
short word[2];
int dword;
}BITS32;
The structure BITS8 represents single byte as 8 separate bits you can access! If you have a variable of type char and you wish to change some of the bits within it, then all you have to do is take its address, cast it to BITS8 * and then you can change whichever bit you like.
char c = 0;
BITS8 *pBits8 = (BITS8 *)&c;
pBits8->bit4 = 1
| bit7 |
bit6 |
bit5 |
bit4 |
bit3 |
bit2 |
bit1 |
bit0 |
Fig.1
The way struct BITS8 represents one byte in memory
If you would want to change the the high an low quater of varialble c, then cast its address to QUATERS * just like this:
char c=0;
QUATERS *pQuaters=(QUATERS *)&c;
pQuaters->quater0 = 0xC;
pQuaters->quater1 = 0xD;
Fig.2
The way struct QUATERS represents one byte in memory
If you want to set bits, quaters or the whole byte, then use the BITSQUTERS * pointer this way:
char c=0;
BITSQUATERS *pBitsQuaters =(BITSQUATERS *)&c;
pBitsQuaters->byte = 0xFF;
pBitsQuaters->quaters.quater0 = 0xC;
pBitsQuaters->quaters.quater1 = 0xD;
pBitsQuaters->bits.bit7 = 0;
| BYTE |
| quater1 |
quater0 |
| bit7 |
bit6 |
bit5 |
bit4 |
bit3 |
bit2 |
bit1 |
bit0 |
Fig.3
The way union BITSQUATERS represents one byte in memory
Here is how to set up dword, low and high word, separate bytes and bits as well — using a BITS32 * pointer:
int i = 0;
BITS32 * pbits32 = (BITS32 *) &i;
pbits32->dword = 0x33221100;
pbits32->word[0] = 0xcc11;
pbits32->byte[0].byte = 0xff;
pbits32->byte[0].quaters.quater0 = 0xF;
pbits32->byte[3].bits.bit7 = 1;
| DWORD |
| WORD1 |
WORD0 |
| byte3 |
byte2 |
byte1 |
byte0 |
| quater1 |
quater0 |
quater1 |
quater0 |
quater1 |
quater0 |
quater1 |
quater0 |
| bit7 |
bit6 |
bit5 |
bit4 |
bit3 |
bit2 |
bit1 |
bit0 |
bit7 |
bit6 |
bit5 |
bit4 |
bit3 |
bit2 |
bit1 |
bit0 |
bit7 |
bit6 |
bit5 |
bit4 |
bit3 |
bit2 |
bit1 |
bit0 |
bit7 |
bit6 |
bit5 |
bit4 |
bit3 |
bit2 |
bit1 |
bit0 |
Fig.4
The way union BITS32 represents one double word in memory
Hope that will come in handy! Enjoy