Reputation: 2973
I am confused as to what the following code does, I understand Line 1 sets a flag, line 2 clears a flag and line 3 toggles a flag;
#include <stdio.h>
#define SCC_150_A 0x01
#define SCC_150_B 0x02
#define SCC_150_C 0x04
unsigned int flags = 0;
main () {
flags |= SCC_150_A; // Line 1
flags &= ~SCC_150_B; // Line 2
flags ^= SCC_150_C; // Line 3
printf("Result: %d\n",flags); // Line 4
}
What I don't understand is what the output of Line 4 would be? What is the effect of setting/clearing/toggling the flags on 0x01
0x02
and 0x04
?
Upvotes: 0
Views: 2601
Reputation: 36517
First of all, I'm going to use binary numbers, cause it's easier to explain with them. In the end it's the same with hexadecimal numbers. Also note that I shortened the variable to unsigned char
to have a shorter value to write down (8 bits vs. 32 bits). The end result is similar, just without leading digits.
Let's start with the values:
0x01 = 0000 0001
0x02 = 0000 0010
0x04 = 0000 0100
So after replacing the constant/macro, the first line would essentially be this:
flags |= 0000 0001
This performs a bitwise or operation, a bit in the result is 1
, if any of the input values is 1
at that position. Due to the initial value of flags
being 0
, this will work just like an assignment or addition (which it won't in general, keep that in mind).
flags: 0000 0000
op: 0000 0001
----------------
or: 0000 0001
The result is flags
being set to 0000 0001
.
flags &= ~0000 0010
Here we've got two operations, first there's ~
, the bitwise complement operator. What this essentially does is flipping all bits of the value. Therefore 0000 0010
becomes 1111 1101
(0xfd
in hex). Then you're using the bitwise and operator, where a result bit is only set to 1
if both input values are 1
at the specific position as well. As you can see, this will essentially cause the second bit from the right to be set to 0
without touching any other bit.
flags: 0000 0001
op: 1111 1101
----------------
and: 0000 0001
Due to this, the result of this operation is 0000 0001
(0x01
in hex).
flags ^= 0000 0100
The last operation is the bitwise exclusive or (xor), which will set a bit to 1
only if the input bits don't match (i.e. they're different). This leads to the simple behavior of toggling the bits set in the operands.
flags: 0000 0001
op: 0000 0100
----------------
xor: 0000 0101
In this case the result will be 0000 0101
(0x05
in hex).
For clarification on the last operation, because I think xor might be the hardest to understand here, let's toggle it back:
flags: 0000 0101
op: 0000 0100
----------------
xor: 0000 0001
As you can see, the third bit from the right is equal in both inputs, so the result will be 0
rather than 1
.
Upvotes: 2
Reputation: 399949
The macros define constants that each require a single bit to be represented:
macro hex binary
======================
SCC_150_A 0x01 001
SCC_150_B 0x02 010
SCC_150_C 0x04 100
Initially flags
is 0.
Then it has:
SCC_150_B
.The final result is thus 1012, or 5 in decimal.
Upvotes: 3