Think booleans, not bits
In summary, your professor's solution is better (but still wrong, strictly speaking, see further down) because it uses boolean operators instead of bitwise operators and treating booleans as integers. The expression c==1
to represent "c is true" is incorrect because if c may be a number (according to the stated assignment) then any non-zero value of c is to be regarded as representing true
.
See this question on why it's better not to compare booleans with 0 or 1, even when it's safe to do so.
One very good reason not to use xor
is that this is the bit-wise exclusive or operation. It happens to work in your example because both the left hand side and right hand side are boolean expressions that convert to 1 or 0 (see again 1).
The boolean exclusive-or is in fact !=
.
Breaking down the expression
To understand your professor's solution better, it's easiest to replace the boolean operators with their "alternative token" equivalents, which turns it into better redable (imho) and completely equivalent C++ code:
Using 'not' for '!' and 'and' for '&&' you get
(not a and not b) != c
Unfortunately, there is no logical exclusive_or
operator other than not_eq
, which isn't helpful in this case.
If we break down the natural language expression:
Either a and b are both false or c is true, but not both.
first into a sentence about boolean propositions A and B:
Either A or B, but not both.
this translates into A != B
(only for booleans, not for any type A and B).
Then proposition A was
a and b are both false
which can be stated as
a is false and b is false
which translates into (not a and not b)
, and finally
c is true
Which simply translates into c
.
Combining them you get again (not a and not b) != c
.
For further explanation how this expression then works, I defer to the truth tables that others have given in their answers.
You're both wrong
And if I may nitpick: The original assignment stated that a, b and c can be non-negative numbers, but did not unambiguously state that if they were numbers, they should be limited to the values 0 and 1. If any number that is not 0 represents true
, as is customary, then the following code would yield a surprising answer:
auto c = 2; // "true" in some way
auto a = 0; // "false"
auto b = 0; // "false"
std::cout << ((!a && !b) != c);
// this will output: 1 (!)
// fix by making sure that != compares booleans:
std::cout << ((!a && !b) != (bool)c);