Bit fields in C


Advertisements

Share



Learn C bit fields, bit manipulation, advantages of bit field, shift operator, bitwise operators such as or, xor, not, right shift, left shift with examples, demonstrations.

What is bit field in C?

Bit FieldsWith C you can manipulate individual bits in a variable. Sometimes this is necessary. When programming microcontrollers you must learn how each bit is to be paid attention. Often we must store the condition 0 or 1 in a variable only. If we take to the smallest well-known data types, i.e. unsigned char, now for the storage of an individual value that needs a single bit, we waste 7 bits, since unsigned char an 8-bit is broad.

Structural padding:The second method of manipulating bits is to use a bit field within a structure. Architecture of a computer processor is such a way that it can read 1 word (4 byte in 32 bit processor) from memory at a time. To make use of this advantage of processor, data are always aligned as 4 bytes package which leads to insert empty addresses between other member’s address. Because of this structure padding concept in C, size of the structure is always not same as what we think. A bit field is used within a structure declaration that labels each field and determines its width. Bit fields within structure are used to save memory space by using bits.

Bitwise shift operators: Bitwise shift operators are widely used in the embedded systems in situations where we need to set/clear/toggle just one single bit of a specific register without modifying the other contents. We can do OR/AND/XOR operations with the appropriate mask for the bit position. Following are the Bitwise shift operators and their functionality.

  • << left shift -----> i << flags is the result when bits in i are shifted left by flags bits and for each bit shifted left is filled by 0's. Left shift is equivalent to multiplying the bit pattern with 2\^k ( if we are shifting k bits 1 << k)
  • >> right shift -----> i >> flags is the result when bits in i are shifted right by flags bits and for each bit shifted right is filled by 0's. Right shift is equivalent to dividing the bit pattern with 2k ( if we are shifting k bits 1 >> k ).
  • ~ bitwise complement ---> ~ operator produces complement of its operand.
  • & bit wise and ---> & operator produces a boolean and operation on all corresponding bits on two operands.
  • ^ bit wise exclusive or ^ operator produces 0 whenever both operands have a 1bit.
  • | bit wise inclusive or \^ operator produces 1 whenever both operands have a 1bit
  • Setting a bit

    Let's write a small program to set bit x in a 32 bit number as shown below.

    
    #include "stdio.h"
    unsigned int SetBit(unsigned int ,unsigned int );
    void main()
    {
      unsigned int number = 0xFFFFFFF0;
      number = SetBit(number,0);
      printf("SetBit Result is 0x%x\n",number);
    }
    unsigned int SetBit(unsigned int num,unsigned int x)
    {
      return num |= 1 << x;
    }
    
    Program output:
    ==============
    $ gcc prog.c
    $ ./a.out
    SetBit Result is 0xfffffff1
    $
    

    Clearing one or more bits

    Let's write a small program to clear bit x in a 32 bit number as shown below.

    
    #include "stdio.h"
    unsigned int ClearBit(unsigned int ,unsigned int );
    void main()
    {
      unsigned int number = 0xfffffff1;
      number = ClearBit(number,0);
      printf("ClearBit Result is 0x%x\n",number);
    }
    unsigned int ClearBit(unsigned int num,unsigned int x)
    {
      return num &= ~(1 << x);
    }
    
    Program output:
    ==============
    $ gcc prog.c
    $ ./a.out
    ClearBit Result is 0xfffffff0
    $
    
  • Clearing more than 1 bit
  • Let's write a small program to clear more than 1 bit at a time in a 32 bit number as shown below.

    
    #include "stdio.h"
    #define START 24
    #define END 31
    unsigned int ClearBits(unsigned int ,unsigned int ,unsigned int );
    void main()
    {
      unsigned int number = 0xFFFFFFF0;
      number = ClearBits(number,START,END);
      printf("ClearBits result is 0x%x\n",number);
    }
    unsigned int ClearBits(unsigned int num,unsigned int start,unsigned int end)
    {
      unsigned int i;
      for(i = start;i <= end;i++)
      {
        num &= ~(1 << i);
      }
      return num;
    }
    
    Program output:
    ==============
    $ gcc prog.c
    $ ./a.out
    ClearBits result is 0xfffff0
    $
    

    Toggling a bit

    Let's write a small program to toggle bit x in a 32 bit number as shown below.

    
    #include "stdio.h"
    unsigned int ToggleBit(unsigned int ,unsigned int );
    void main()
    {
      unsigned int number = 0xfffffff0;
      number = ToggleBit(number,0);
      printf("ToggleBit result is 0x%x\n",number);
      number = ToggleBit(number,0);
      printf("ToggleBit result is 0x%x\n",number);
    }
    unsigned int ToggleBit(unsigned int num,unsigned int x)
    {
      return num ^= (1 << x);
    }
    
    Program output:
    ==============
    $ gcc prog.c
    $ ./a.out
    ToggleBit result is 0xfffffff1
    ToggleBit result is 0xfffffff0
    $
    

    Checking a bit value

    Let's write a small program to checking a bit value in a 32 bit number as shown below.

    
    #include "stdio.h"
    unsigned int CheckBit(unsigned int ,unsigned int );
    void main()
    {
      unsigned int number = 0xFFFFFFF0;
      number = CheckBit(number,2);
      printf("Check result is %d\n",number);
    }
    unsigned int CheckBit(unsigned int num,unsigned int x)
    {
      if(((num >> x) & 1) == 0)
      {
        return 0;
      }else
      {
        return 1;
      }
    }
    Program output:
    ==============
    $ gcc prog.c
    $ ./a.out
    Check result is 0
    $
    

    Structural padding

    
    #include "stdio.h"
    struct TIME
    {
      unsigned int seconds : 6; //6bits required for representing 60seconds
      unsigned int minutes : 6; //6bits required for representing 60minutes
      unsigned int hours : 5; //5bits required for representing 24hrs
      //padding of 15bits will take place as processor is of 32 bits
    };
    void main()
    {
      printf("Size of struct time is %d\n",sizeof(struct TIME));
    }
    
    Program output:
    ==============
    $ gcc prog.c
    $ ./a.out
    Size of struct time is 4
    $
    

    Notice that in the above program we have declared structure TIME to represent time. To represent 60 seconds as 1 minute we used 6 bits as 6 bits can be used to represent up to 2^6=64. Similarly to represent 60 minutes as 1 hour we used 6 bits. To represent 24 hours of a day we use 5bits as 5bits can be used to represent upto 2^5=32. This way we can use the bits efficiently. So if the processor can process 4bytes=32 bits at a time we should align bits accordingly. If we didn't align all 32 bits, processor will do padding automatically to fill up the remaining bits. That is the reason when we calculate the size of struct TIME in line 55 it gives 4 bytes.

    Exercises, Solutions

    High
    Medium
    High
    High
    Medium
    Medium
    Medium

    Want to contribute a new article? Write and upload your article information .
    Share

     Articles

     C Programming

     Linux Software

     Test your skills:online tests

     C Programming

     Python Programming

     Linux Software

     Quantitative Aptitude

     Embedded System Software

     Search Code Snippets

     Popular C search examples

     Popular C search MCQs