Bit Fields in C – What is Bit Field in C Programming

Bit Fields in C – What is Bit Field in C Programming

Bit fields in C are fairly basic in comparison to anything we have covered thus far. The memory allocation for unions and structures is made easier 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.

You must test the C Language code provided in this lesson in your code editor to validate it. However, if you prefer to execute this code online, we also provide a free C Online Compiler for testing your C Language code.

Bit Fields in C Language

Best wallets to store your Bitcoins...
Best wallets to store your Bitcoins - Pousada Nerd

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

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 Bit Fields in C

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 Bit Fields in C

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, minutes, and seconds should be from 0 to 59.

You can try to test here the example above!

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 try to test here the example above!

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 try to test here the example above!

Listed below are some interesting facts concerning bit fields in C.

An unnamed bit field of size 0 is used to compel alignment on the next boundary. Consider the following program as an example.

#include <stdio.h>
// A structure without forced alignment
struct tutorial1 {
  unsigned int a : 5;
  unsigned int b : 8;
};
// A structure with forced alignment
struct tutorial2 {
  unsigned int a : 5;
  unsigned int : 0;
  unsigned int b : 8;
};
int main()
{
  printf("Size of tutorial1 is %lu bytes\n",
    sizeof(struct tutorial1));
  printf("Size of tutorial2 is %lu bytes\n",
    sizeof(struct tutorial2));
  return 0;
}

Output of the above example

Size of tutorial1 is 4 bytes
Size of tutorial2 is 8 bytes

You can try to test here the example above!

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 try to test here the example above!

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.

Inquiries

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 details. 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