Structures in C are used to group multiple variables of the same or different types. The variables inside the structures can be accessed through its structure variables. I recommend you to read the article, “C Programming – Understanding Structures in C“, before proceeding with this.
Usually, ‘C’ structures are to group related information.
‘C’ compiler allocates memory for each variable mentioned in the structures. The size of the memory ‘C’ allocates is depends on the type of the variable. We can inform the ‘C’ compiler to allocate the size of the memory for each variable by using bit fields.
The least memory size allocated for a variable is one byte (1 byte). But how do we allocate memory of only one bit (1 bit) for a variable? It is possible through bit fields.
Below is the syntax to define bit fields in ‘C’ structures.
struct <structure name> { <data type 1> <variable name 1> : <width>; ... <data type N> <variable name N> : <width>; };
The above structure declaration is almost the same as the normal structure declaration; except that <width>
field. <width>
field indicates the number of bits to allocate to the variable.
There is a condition when specifying the <width>
field. The number of bits mentioned in the <width>
field must be less than or equal to the maximum number of bits allowed to the data type of the variable. For example, if the data type of the variable is “int
” and maximum allowed bits for this type is 32 bits (usually); in <width>
field, we should specify the value less than or equals to 32. If we provide the value greater than 32 as the <width>
value, the ‘C’ compiler will throw the below error.
error: width of ‘var’ exceeds its type
Bit fields are mainly useful in low-level programming.
Let’s take a simple example to understand how to deal with bit fields in ‘C’ structures.
// Sample.c #include <stdio.h> struct Byte { 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; unsigned char bit8 : 1; }; void main() { printf("\nunsigned char: %d Byte(s)", sizeof(unsigned char)); printf("\nByte: %d Byte(s)", sizeof(struct Byte)); struct Byte byte = {0, 1, 0, 0, 0, 0, 0, 0}; printf("\nByte Value: %d", byte); }
From the above code, we have a Byte structure with “unsigned char” variables, and only “1 bit” is allotted for each variable. The purpose of this Byte structure is to store and retrieve each bit’s value in an “unsigned char” variable.
After that, the code displays the size of Byte
structure; on my system, it is displayed as “1 Byte” of size. So, if we declare a normal structure, it will display as “8 Byte(s)” of size for the same structure; we saved the memory by using bit fields.
Once the structure is declared, each bit value is assigned and displays the result. Now, we have the flexibility to access each bit in an “unsigned char” value.
I have compiled and executed this program on my CentOS 64-bit Operating System and I got the below result.
unsigned char: 1 Byte(s) Byte: 1 Byte(s) Value is: 2
// Malin