Bit Fields in C Language with Example

Bit fields in C are relatively basic compared to anything we have covered thus far.

The memory allocation for unions and structures is made more accessible by bit fields, which are merely data structures.

The size (in bits) of a structure’s or union’s members can be specified in C.

When we know that the value of a field or group of fields will never go over a threshold or is contained inside a narrow range, the goal is to use memory efficiently.

Bit Field in C Language

A bit field is a data structure that, according to programming jargon, enables the programmer to assign memory to structures and unions in bits to use computer memory effectively.

Because unions and structures in C are user-defined data types, the user is aware of how much memory they will require.

As a result, memory management is made simple and effective by the use of bit fields.

Need for C Bit Fields

Because of the following, bit fields play a significant role in C programming:

  • used to cut down on memory usage.
  • Simple to implement
  • allows the code to be flexible.

Declaration of C Bit Field

Declaring a bit field is rather simple. This is what it declares:

struct
{
data_type variable_name : size_in_bits;
};

The width of the bit field is the official term for size in bits.

How do Bit Fields in C works?

Let’s look at a situation where we need to construct a structured time to display the time according to a 24-hour clock input by the user with unsigned int hours, minutes, and seconds in order to learn how bit fields function.

The size of the structure would be 12 bytes since a 64-bit compiler estimates that an unsigned integer takes up 4 bytes of memory.

Here is some C code that demonstrates how to build a structured time without bit fields:

#include <stdio.h>
struct time
{
unsigned int hrs;
unsigned int min;
unsigned int sec;
}; 
int main()
{
struct time t = {11, 30, 10}; // Here t is an object of the structure time
printf("Welcome to Bit Fields tutorials!\n\n");
printf("The time is %d : %d : %d\n", t.hrs, t.min, t.sec);
printf("The size of time is %ld bytes.\n", sizeof(struct time));
return 0; 
}

Output of the above example:

Welcome to Bit Fields tutorials!

The time is 11 : 30 : 10
The size of time is 12 bytes.

Clearly, we know that, for a 24-hour clock, the range of hours should be from 0 to 23, and minutes and seconds should be from 0 to 59.

You can test the above example here! ➡ C Online Compiler

Take the following date declaration without bit fields as an example.

#include <stdio.h>
// A simple representation of the date
struct date {
  unsigned int d;
  unsigned int m;
  unsigned int y;
};
int main()
{
  printf("Size of date is %lu bytes\n",
    sizeof(struct date));
  struct date dt = { 07, 05, 2022 };
  printf("Date is %d/%d/%d", dt.d, dt.m, dt.y);
}

Output of the above example:

Size of date is 12 bytes
Date is 7/5/2022

On a compiler, the aforementioned form of “date” uses 12 bytes, as opposed to an unsigned int’s 4 bytes.

We may use bit fields to maximize the space since we know that the value of d is always between 1 and 31 and the value of m is between 1 and 12.

However, if the identical code was written using signed int and the value of the fields exceeded the number of bits allotted to the variable, interesting things might occur.

You can test the above example here! ➡ C Online Compiler

Consider the same code using signed integers, for example:

#include <stdio.h>
// Space optimized representation of the date
struct date {
  // d has value between 0 and 31, so 5 bits
  // are sufficient
  int day : 5;
  // m has value between 0 and 15, so 4 bits
  // are sufficient
  int month : 4;
  int year;
};
int main()
{
  printf("Size of date is %lu bytes\n",
    sizeof(struct date));
  struct date dt = { 05, 07, 2022 };
  printf("Date is %d/%d/%d", dt.day, dt.month, dt.year);
  return 0;
}

Output of the above example:

Size of date is 8 bytes
Date is 5/7/2022

It turns out that the output is negative. The value 31 was saved in a 5-bit signed integer, which is equivalent to 11111, in the background.

The binary number’s real value must be determined by computing the 2’s complement of the binary number, which is what is done internally because the MSB is a 1, making it a negative integer.

By adding the two numbers together, you can get the value 00001, which is equal to the decimal number 1 and, because it was a negative number, a -1.

Similar circumstances apply to 12, in which case you receive a 4-bit representation as 1100 and, after computing 2’s complement, receive the number -4.

You can test the above example here! ➡ C Online Compiler

Bit Field Declaration

Within a structure, the declaration of a bit-field has the following format:

struct {
   type [member_name] : width ;
};

The subsequent table outlines the variable components of a bit field.

ElementDescription
typeA type of integer that determines how the value of a bit-field is interpreted. Int, signed int, or unsigned int may be used.
member_nameThe designation of the bit-field.
widthThe quantity of bits within the bit-field. The width must be less than or equal to the specified type’s bit width.

The variables with a predetermined width are referred to as bit fields.

A bit field can include multiple bits; for instance, if you need a variable to store a value between 0 and 7, you can define a bit field with a width of 3 bits as follows:

struct {
   unsigned int age : 3;
} Age;

The preceding structure description notifies the C compiler that the age variable will store its value using only three bits.

If you attempt to use more than 3 bits, you will be prevented from doing so.

Consider the following example:

Sizeof( Age ) : 4
Age.age : 4
Age.age : 7
Age.age : 0

You can test the above example here! ➡ C Online Compiler

Summary

This tutorial explained bit fields, their significance, and how they function.

By completing this tutorial, we have advanced in our understanding of the C programming language.

If you have any questions or suggestions about Bit Fields in C – What is Bit Field in C Programming, please feel free to leave a comment below.

About Next Tutorial

In the next following post, I’ll create a typedep in C and try to explain its many components in full detail.

I hope you enjoy this post on Bit Fields in C – What is Bit Field in C Programming, in which I attempt to illustrate the language’s core grammar.


Leave a Comment