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:
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:
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:
So we can apply bitwise operators like this:
Now assume option A is 0x5 and option B is 0x7:
As you may notice, both options are now set into C.
Here we will use our other operator:
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.
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:
And that is simply it. You may call the program using any which option you wish, some examples include:
And that concludes the lesson!
All Credits goes to one who really made this...
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;
Code:
enum Options {
OPT_A = 0x01,
OPT_B = 0x02,
OPT_C = 0x04,
OPT_D = 0x08,
OPT_E = 0x10,
OPT_F = 0x20,
};
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 |
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]
Here we will use our other operator:
Code:
Bitwise AND, A & B = C
[FONT=Courier New] 00000101 (0x5)
AND 00000011 (0x3)
= 00000001 (0x1)[/FONT]
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!");
}
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;
}
Code:
./arguments -a -b
./arguments -abc
./arguments -h
./arguments -z
All Credits goes to one who really made this...