The concept of ‘Bit Field’ is used when we know the fixed length or range of values held by the structure member. Normally we use the primitive data type like char, int, short to decide the maximum and minimum value of the variable but sometimes we know about the exact length of data which is very less than assigned space by primitive data type then we can save memory by utilizing the concept of the bit field.
suppose you want to store your birth date i.e. date, month, year.
date <=31———–> maximum 5 bit required.
month <=12——- —> maximum 4 bit required
year <=2017(assume)—>maximum 12 bit required.
see this table to compare the bit field and non-bit field structure
structure member | Without Bit Field | With Bit Field |
---|---|---|
date | unsigned int date | unsigned int date :5 |
month | unsigned int month | unsigned int month :4 |
year | unsigned int year | unsigned int year :12 |
Total space occupied in memory | 12 byte | 4 byte |
So from the above table, we can conclude that bit field plays a very important role where memory is very limited.
Bit field use: operator to bound a variable in fixed length.
Bit field syntax :
1 |
structure member : data length; |
To understand this article, I assume that you are familiar with structure concept.let’s take a structure for your birth date.
1 2 3 4 5 6 |
struct birthday1 { unsigned int date; // 4 byte occupied for date due to unsigned int unsigned int month; // 4 byte occupied for month due to unsigned int unsigned int year; // 4 byte occupied for year due to unsigned int }; |
1 |
Space occupied in memory for birthday1 : 12 Byte |
12-byte space is reserved due to 3 unsigned int variable while the actual data requires only 17 bit. we can optimize the size using bit field concept in the above structure.
1 2 3 4 5 6 |
struct birthday1 { unsigned int date :5 ;// 32bit - 5bit=30bit unsigned int month :4 ;// 30bit - 4bit=26bit unsigned int year :12;// 26bit - 12bit=14bit left }; |
1 |
Space occupied in memory : 4 Byte |
Note: Although the required memory is 17 bit in above structure space occupied by this structure is 4 byte i.e. 32 bit because minimum memory occupied by an integer is 4 byte on a 32-bit processor.
so if the size of the structure is <32 bit then it will automatically reserve 32-bit space.
As seen in the second structure all three members are packed into 32-bit space instead of occupying 32 bit each. we have bounded all member on their fixed length as explained in the table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <stdio.h> #include <stdlib.h> struct birthday1 { unsigned int date :5 ; // 32bit - 5bit=30bit unsigned int month :4 ; // 30bit - 4bit=26bit unsigned int year :12; // 26bit - 12bit=14bit left }; struct birthday2 { unsigned int date ; // 32bit unsigned int month ; // 32bit unsigned int year ; // 32bit }; int main() { struct birthday1 bday1={15,10,1990}; struct birthday2 bday2={15,10,1990}; printf("Size of birthday1=%d\n", sizeof(bday1)); printf("birthday1 is=%d/%d/%d\n",bday1.date,bday1.month,bday1.year); printf("Size of birthday2=%d\n", sizeof(bday2)); printf("birthday2 is=%d/%d/%d\n",bday2.date,bday2.month,bday2.year); return 0; } |
1 2 3 4 |
Size of birthday1=4 birthday1 is=15/10/1990 Size of birthday2=12 birthday2 is=15/10/1990 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <stdio.h> #include <stdlib.h> struct birthday { unsigned char date :5 ; unsigned char month :2 ; short int year :12; }; int main() { struct birthday bday={15,3,2017}; printf("Structure member 'date' stored at =%p\n",&bday.date); } |
1 |
error: cannot take address of bit-field 'date' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <stdio.h> #include <stdlib.h> struct birthday { unsigned char date :5 ; unsigned int:0; //1st 4 byte jump unsigned char month :4 ; unsigned int:0; //2nd 4 byte jump short int year :12; }; int main() { struct birthday bday={15,3,2017}; printf("Size of structure =%d\n",sizeof(bday)); } |
1 |
Size of structure =10 |
Note: If you are using multiple times continues jump then it will consider only once.
1 2 3 4 5 6 7 8 9 10 |
struct birthday { unsigned char date :5 ; unsigned int:0; //1st 4 byte jump unsigned int:0; //wrong, no effect unsigned int:0; //wrong, no effect unsigned char month :4 ; unsigned int:0; //2nd 4 byte jump short int year :12; }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <stdio.h> #include <stdlib.h> struct birthday { unsigned char date :5 ; unsigned char month :9 ; //bit lenght exceed from its data type short int year :12; }; int main() { struct birthday bday={15,10,2017}; printf("Size of structure =%d\n",sizeof(bday)); printf("birthday is=%d/%d/%d\n",bday.date,bday.month,bday.year); } |
1 2 |
error: width of 'month' exceeds its type unsigned char month :9 ; |
1 2 3 4 5 6 |
struct birthday { unsigned char date :5 ; unsigned char month[10] :9 ; //Array of bit field not allowed short int year :12; }; |
Although I have tried to cover most of the part related to this topic your suggestion and comment is always welcome to improve this article. I also request you to send me if you find any error in this article .thank you so much for reading 🙂.