Bit Flags Tutorial with Example

Status
Not open for further replies.

Baljeet

Member
Jan 31, 2011
76
0
C/C++: Bit Flags

What are bit flags?

Bit flags , or bit fields are a great way of storing several boolean values in a single byte (or set of bytes), and are internally represented as binary. In this tutorial we will work with bitwise operators, so if you need to brush up this is what we're using; the following key binary operators.

Here they are:

AND (a & b): Bits that are set in both a and b are set.
OR: (a | b): Bits that are set in either a or b are set.
XOR (a ^ b): Bits that are set in a or b but not both are set.
NOT (~a) : Bits in a are complemented (inversed)

In this lesson we will need to work with an unsigned integer, which can store successfully four bytes of data but for simplicity's sake we will only work with one (a char in this case). Note that one byte = eight bits:
Code:
[COLOR=blue]unsigned char[/COLOR] options;
We will need to define the required options and their bits in an enum field, in here the options will be placed at separate bits in the byte. You may note my simple naming convention, we should avoid using anything too fancy here:

Code:
enum Options {
    OPT_A   = 0x01,
    OPT_B   = 0x02,
    OPT_C   = 0x04,
    OPT_D   = 0x08,
    OPT_E   = 0x10,
    OPT_F   = 0x20,
};
Each option will now have its own bit flag, what we will need to understand is its binary representation so we can successfully use bitwise operators. The simple conversion from hexadecimal on what we defined is as follows:

Code:
 00000000 Meaning       Bin Hex    | Examples
 ???????? Preference 1  2^0   1    | Pref 1+2   is Hex 3 is 00000011
 ???????? Preference 2  2^1   2    | Pref 1+8   is Hex 81 is 10000001
 ???????? Preference 3  2^2   4    | Pref 3,4+6 is Hex 2C is 00101100
 ???????? Preference 4  2^3   8    | all Prefs  is Hex FF is 11111111
 ???????? Preference 5  2^4  10    |
 ???????? Preference 6  2^5  20    | etc ...
 ???????? Preference 7  2^6  40    |
 ???????? Preference 8  2^7  80    |
So we can apply bitwise operators like this:

Now assume option A is 0x5 and option B is 0x7:
Code:
Bitwise OR, A | B = C:
[FONT=Courier New]   00000101 (0x5)
OR 00000011 (0x3)
 = 00000111 (0x7)[/FONT]
As you may notice, both options are now set into C.

Here we will use our other operator:
Code:
Bitwise AND, A & B = C
[FONT=Courier New]    00000101 (0x5)
AND 00000011 (0x3)
  = 00000001 (0x1)[/FONT]
A & B = decimal ONE, therefor we can assume B is set as it is non-zero.


This next part I will explain how we may use it in our code, this example shows setting three options (options A, E and F) and then verifying if option F was is set.

Code:
//       8*1b            0x1    0x10    0x20  =  0x31
unsigned char options = OPT_A | OPT_E | OPT_F;

//     0x31 & 0x20 = 0x20 > 0 = true
if (options & OPT_F) {
    printf("Option F is set!");
}
That is essentially it. There are many different aspects of the program you can use bit fields for, from dealing with database formats or setting flags for user permissions. It is a simple and clean method of storing key values without wasting variable space.

As people tend to like darned examples instead of just a lecture, I will write something full to include arguments in my example application!

arguments.c:
Code:
#include <stdio.h>

//anonymous enum of options, can be done any way you wish
enum {
    OPT_A = 0x01,
    OPT_B = 0x02,
    OPT_C = 0x04,
    OPT_H = 0x08,
};

int main(int argc, char **argv)
{
    //unsigned int, or rather uint32_t = 8*4=32 bits for options if needed, unsigned means last bit is ours to use
    unsigned int opt = 0x0;
    //can do char array for options like '-nodebug'
    char c;

    //extract arguments from argument array.
    while((++argv)[0] && argv[0][0] == '-')
    {
        while((c = *++argv[0]) != 0)
        {
            switch(c) { 
            case 'a':
            //assign option bits to "opt" bit array
                opt |= OPT_A;  break;
            case 'b':
                opt |= OPT_B;  break;
            case 'c':
                opt |= OPT_C;  break;
            case 'h':
                opt |= OPT_H;  break;
            //this will happen if they enter an invalid option:
            default: 
                printf("%s: Unknown option %c", argv[0], c);
                return 1; //break out of application
            }
        }
    }
    
    //apply bitwise AND to check for assignedness a few times
    if(opt & OPT_A)
        printf("Hello World!\n");
   
    if(opt & OPT_B) {
        unsigned int foo;
        foo = 2000;
        printf("Foo has been initialized.\n");
    }
    
    //compare if two flags were specifically set
    if ((opt & (OPT_B | OPT_C)) == (OPT_B | OPT_C)) 
        printf("Flags B and C were set.\n");
    
    if(opt & OPT_H) {
        //print help, may wish to create exit point to stop program from executing
        printf("\tHelp is not implemented yet\n\tAllowable options: [-abch]\n");
        return 0;
    }
  
    //----------------- Some fun extras: ---------------------//
    
    //Reset bitflag completely
    opt = 0;
    
    //Apply bitwise OR to append multiple flags
    opt = (OPT_A | OPT_B | OPT_C);
    
    //Apply bitwise AND+EQUALS to add or remove flags to existing option field
    //Then we apply bitwise NOT (a complement) to remove both flags
    opt &= ~(OPT_A | OPT_B);
    
    //Options A and B are now removed
    
    //Check if BOTH flags are not set
    if ((opt & (OPT_A | OPT_B)) == 0)
        //printf( A and B are not set )

    //check if only one is not set
    if ((opt & OPT_A) == 0)
        //printf( flag A is not set )
        
    //end program
    return 0;
    
}
And that is simply it. You may call the program using any which option you wish, some examples include:
Code:
./arguments -a -b
./arguments -abc
./arguments -h
./arguments -z
And that concludes the lesson!

All Credits goes to one who really made this...
 

extacy

Member
Jan 6, 2011
106
2
Stop posting stolen TUT's
where ever your getting thease save the web address and the username that posted it and put real credits, you just basicly boosting your posts.
if we all just took other peoples posts and posted them again it would start to get annoying
 
Status
Not open for further replies.

Users who are viewing this thread

Top