C Programming

Bit Fields in C

Space Complexity is the most important criterion in the C language. We study a language to develop any software. The main observation of a product is to manage data in our memory. Bit field helps us to manage data in the C language. It helps us to consume memory less than its requirement. In this article, we will discuss the concept of bit fields and their application.

Characteristics of a Variable

Bit fields are used to consume memory efficiently in such a way that we manage our memory space in a smooth manner.

It can be used in structure and union too.

How To Implement a Bit Field in the C Program

1
2
3
4
5
6
7
8
9
10
11
struct date

{

unsigned  int  d  ;

unsigned  int  m ;

unsigned  int  y ;

} ;

Explanation

The variable of type, “date”, takes 12 bytes on a compiler which are 32 bits on a 64-bit compiler, whereas “date” takes 6 bytes on a compiler which are 16 bits.

64 bits

d1
d m y
22 1 2016
4 bytes 4 bytes 4 bytes
= 12 bytes

32 bits

d1
d m y
22 1 2016
2 bytes 2 bytes 2 bytes
= 6 bytes

How To Reduce the Size of a Variable in a Program

Programming Example 1

In this programming example, we will see what amount of memory is consumed by any type of variable.

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
#include <stdio.h>

struct date //  Defining user defined data type.

{


    unsigned  int d ;       // data member of date data type.
    unsigned  int  m ;
    unsigned  in t y ;


} ;

int main ()

{

struct  date d1 = { 22, 1, 2016 } ; // date type variable is declared and initialized.

printf ( " Size of d1 is %d ",  sizeof ( d1 ) ) ;

return 0 ;

}

Output

Explanation

The values of the date and month are fixed: the Date is 31, and the Month is 12.

2 31
2 15-2
2 7-1
2 3-1
1-1
2 12
2 6-0
2 3-0
1-1
11111 1100 1100
(5 bits)  (4 bits)

From the previous calculation of the date, we are trying to say that to represent a maximum day in a month (31), only 5 bits of memory are required out of 4 bytes or 32 bits. It is the same also in the case of counting months. There are 12 months in a year. To represent 12 in the memory, it takes only 4 bits out of 4 bytes or 32 bits. Thus, it is clear from this perception that the rest of the memory is wasted in the case of day and month on a date. In this situation, the bit field helps us to solve the problem.

Programming Example 2

In this programming example, we will use the bit field to consume memory for the variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

struct date //  Defining user defined data type.

{

    unsigned  int d : 5 ;       // data member of date data type.
    unsigned  int m : 4 ;   // using bit field as colon :
    unsigned  int y ;


} ;

int main ()

{

struct date d1 =  { 22,  1,  2016 } ; // date type variable is declared and initialized.

printf  ( " Size of d1 is %d ",  sizeof ( d1 ) ) ;

return 0 ;

}

Output:

Explanation

We know that the value of d is always from 1 to 31. One year contains 12 months. So, the initialization value of month variable, m, is a maximum of 12. We can handle the extra space with the help of bit fields.

Improved Example

Single memory bytes

[4 bytes]

Memory block is created multiple of 4 bytes.

The variable d1 of type “date” takes 8 bytes on a compiler, whereas an unsigned integer takes 4 bytes.

Programming Example 3

We will see another example of memory consumption without using a bit field.

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
27
#include <stdio.h>

struct tm

{

unsigned  int  hrs ;

unsigned  int  min ;

unsigned  int sec ;

} ;

int main ()

{

struct tm t  =   {11,  30,  10 } ; // declaration of a variable of user defined type.

printf ( " The time is %d : %d : %d\n ",  t.hrs, t.min, t.sec ) ;

printf ( " The size of clock = %ld bytes.\n ",  sizeof ( struct tm ) ) ;

return 0 ;

}

Output

Explanation

From the previous calculation of the date, we are trying to say that to represent the maximum seconds in an hour (60), only a 6-bit memory is required out of 4 bytes or 32 bits. It is the same also in the case of counting the minutes. There are 60 minutes in an hour. To represent 60 in the memory, it takes only 5 bits out of 4 bytes or 32 bits. So, it is clear from this perception that the rest of the memory is wasted in the case of day and month on a date. This problem will be solved with the help of the bit field.

Programming Example 4

Here, we can see another application of bit fields.

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
27
#include <stdio.h>

struct tm

{

unsigned  int  hrs : 8  ;

unsigned  int  min : 10 ;

unsigned  int  sec : 10 ;

} ;

int main()

{

struct tm t  =  { 11,  30,  10 } ;   // declaration of a variable of user defined type.

printf ( " The time is %d : %d : %d\n ",  t.hrs, t.min, t.sec ) ;

printf ( " The size of clock = %ld bytes.\n ",  sizeof ( struct tm ) ) ;

return 0 ;

}

Output

Explanation

In this programming example, we use bit field to consume memory. As we see from the example, we will use the bit field (:) after declaring every data member of the time data type, trying to consume bits in a memory location. As a result, we will see from the output memory is consumed.

Conclusion

From the previous declaration, it is evident that we have to use the bit field to manage space complexity in the C language. Bit field helps us to remove extra wasted memory allocation from the memory to manage space complexity. So, we must use the bit field in a very conscious manner where it is required. Otherwise, data may be wasted.

About the author

Bamdeb Ghosh

Bamdeb Ghosh is having hands-on experience in Wireless networking domain.He's an expert in Wireshark capture analysis on Wireless or Wired Networking along with knowledge of Android, Bluetooth, Linux commands and python. Follow his site: wifisharks.com