Interview answers verified by specialists.

Find interview questions and answers on this website:

See right interview answers on 30 common job interview questions

What is meant by "bit masking"?

Bit masking means selecting only certain bits from byte(s) that might have many bits set. To examine some
bits of a byte, the byte is bitwise "ANDed" with a mask that is a number consisting of only those bits of interest.
For instance, to look at the one's digit (rightmost digit) of the variable flags, you bitwise AND it with a mask
of one (the bitwise AND operator in C is &):

flags & 1;

To set the bits of interest, the number is bitwise "ORed" with the bit mask (the bitwise OR operator in C is
|). For instance, you could set the one's digit of flags like so:

flags = flags | 1;

Or, equivalently, you could set it like this:

flags |= 1;

To clear the bits of interest, the number is bitwise ANDed with the one's complement of the bit mask. The
"one's complement" of a number is the number with all its one bits changed to zeros and all its zero bits
changed to ones. The one's complement operator in C is ~. For instance, you could clear the one's digit of
flags like so:

flags = flags & ~1;

Or, equivalently, you could clear it like this:

flags &= ~1;

Sometimes it is easier to use macros to manipulate flag values.

Example Program : Macros that make manipulating flags easier.

/* Bit Masking */
/* Bit masking can be used to switch a character
   between lowercase and uppercase */
#define BIT_POS(N)            ( 1U << (N) )
#define SET_FLAG(N, F)        ( (N) |= (F) )
#define CLR_FLAG(N, F)        ( (N) &= -(F) )
#define TST_FLAG(N, F)        ( (N) & (F) )
#define BIT_RANGE(N, M)       ( BIT_POS((M)+1 - (N))-1 << (N) )
#define BIT_SHIFTL(B, N)      ( (unsigned)(B) << (N) )
#define BIT_SHIFTR(B, N)      ( (unsigned)(B) >> (N) )
#define SET_MFLAG(N, F, V)    ( CLR_FLAG(N, F), SET_FLAG(N, V) )
#define CLR_MFLAG(N, F)       ( (N) &= ~(F) )
#define GET_MFLAG(N, F)       ( (N) & (F) )
#include <stdio.h>
void main()
  unsigned char ascii_char = 'A';        /*  char = 8 bits only */
  int test_nbr = 10;
  printf("Starting character = %c\n", ascii_char);
  /*  The 5th bit position determines if the character is
      uppercase or lowercase.
      5th bit = 0  - Uppercase
      5th bit = 1  - Lowercase      */
  printf("\nTurn 5th bit on = %c\n", SET_FLAG(ascii_char, BIT_POS(5)) );
  printf("Turn 5th bit off = %c\n\n", CLR_FLAG(ascii_char, BIT_POS(5)) );
  printf("Look at shifting bits\n");
  printf("Current value = %d\n", test_nbr);
  printf("Shifting one position left = %d\n",
         test_nbr = BIT_SHIFTL(test_nbr, 1) );
  printf("Shifting two positions right = %d\n",
         BIT_SHIFTR(test_nbr, 2) );

BIT_POS(N) takes an integer N and returns a bit mask corresponding to that single bit position (BIT_POS(0)
returns a bit mask for the one's digit, BIT_POS(1) returns a bit mask for the two's digit, and so on). So instead
of writing

#define A_FLAG  4096

#define B_FLAG  8192

you can write

#define A_FLAG  BIT_POS(12)

#define B_FLAG  BIT_POS(13)

which is less prone to errors.

The  SET_FLAG(N, F) macro sets the bit at position F of variable N. Its opposite is  CLR_FLAG(N, F), which clears
the bit at position F of variable N. Finally, TST_FLAG(N, F) can be used to test the value of the bit at position
F of variable N, as in

if (TST_FLAG(flags, A_FLAG))
        /* do something */;

The macro  BIT_RANGE(N, M) produces a bit mask corresponding to bit positions N  through M, inclusive. With
this macro, instead of writing

#define FIRST_OCTAL_DIGIT  7       /* 111 */

#define SECOND_OCTAL_DIGIT 56      /* 111000 */

you can write

#define FIRST_OCTAL_DIGIT  BIT_RANGE(0, 2)    /* 111 */

#define SECOND_OCTAL_DIGIT BIT_RANGE(3, 5)    /* 111000 */

which more clearly indicates which bits are meant.

The macro BIT_SHIFT(B, N) can be used to shift value B into the proper bit range (starting with bit N). For
instance, if you had a flag called C that could take on one of five possible colors, the colors might be defined
like this:

#define C_FLAG          BIT_RANGE(8, 10)      /* 11100000000 */
/* here are all the values the C flag can take on */
#define C_BLACK         BIT_SHIFTL(0, 8)       /* 00000000000 */
#define C_RED           BIT_SHIFTL(1, 8)       /* 00100000000 */
#define C_GREEN         BIT_SHIFTL(2, 8)       /* 01000000000 */
#define C_BLUE          BIT_SHIFTL(3, 8)       /* 01100000000 */
#define C_WHITE         BIT_SHIFTL(4, 8)       /* 10000000000 */
#define C_ZERO          C_BLACK
#define C_LARGEST       C_WHITE
/* A truly paranoid programmer might do this */
        Cause an error message. The flag C_FLAG is not
        big enough to hold all its possible values.
#endif /* C_LARGEST > C_FLAG */

The macro SET_MFLAG(N, F, V) sets flag F in variable N to the value V. The macro CLR_MFLAG(N, F) is identical
to CLR_FLAG(N, F), except the name is changed so that all the operations on multibit flags have a similar
naming convention. The macro GET_MFLAG(N, F) gets the value of flag F in variable N, so it can be tested,
as in

if (GET_MFLAG(flags, C_FLAG) == C_BLUE)
        /* do something */;