Reputation: 4771
I am having trouble trying to understand how logical operators work in C. I already understand how the bit-level operators work, and I also know that logical operators treat nonzero arguments as representing TRUE and zero arguments as representing FALSE
But say we have 0x65 && 0x55. I do not understand why and how this operations gives 0x01.
I tried to convert it to binary, but I cannot figure out how it works
Upvotes: 2
Views: 7142
Reputation: 158449
C and C++ has three logical operators: logical not(!
), logical and(&&
) and logical or(||
). For logical operators, 0
is false and anything that is not zero is true. This truth table illustrates how each logical operator works(will be using 1
for true
):
p q p && q p || q
= = ====== ======
1 1 1 1
1 0 0 1
0 1 0 1
0 0 0 0
The truth table for !
is as follows:
p !p
= ===
1 0
0 1
For your specific case:
0x65 && 0x55
Since both operands 0x65
and 0x55
evaluate to true
the whole expression evaluates to true
and thus expands to 1
, which applies to c99
but other answers in the linked thread explain how it applies before c99
as well.
Upvotes: 0
Reputation: 726479
The &&
is a logical AND
(as opposed to &
, which is a bitwise AND
). It cares only that its operands as zero/non-zero values. Zeros are considered false
, while non-zeros are treated as true
.
In your case, both operands are non-zero, hence they are treated as true
, resulting in a result that is true
as well. C represents true
as 1
, explaining the overall result of your operation.
If you change the operation to &
, you would get a bitwise operation. 0x65 & 0x55
will give you a result of 0x45
.
Upvotes: 1
Reputation: 279215
I tried to convert it to binary
That might have got in the way of understanding. The exact bit-patterns of 0x65
and 0x55
are completely irrelevant to the required result, all that matters is that they're both non-zero. You could consider a = (0x65 && 0x55)
to be equivalent to something like:
if (0x65 != 0) goto condition_false;
if (0x55 != 0) goto condition_false;
a = 1;
goto condition_end;
condition_false:
a = 0;
condition_end:
A given implementation might be able to emit code more efficient than that (although I have seen pretty much that code emitted, with each if ... goto
being a test and branch in the assembly). The more-efficient code might involve some bit operations to avoid branches. For that matter, in this example involving constants the compiler would probably just emit a = 1;
.
The meaning of the &&
operator is in terms of conditional execution, though. For example if you write f() && g()
then it is guaranteed that when f
returns a false value, g
is not called. If it's possible to get the same result by bit-twiddling then that's likely a bonus for performance.
Upvotes: 0
Reputation: 215
As you said the logical operators treat nonzero arguments as representing
(0x65 && 0x55) is equal as (0x65 > 0) && (0x55 > 0)
0x65 > 0 get true and 0x55 > 0 get true as well
So (0x65 && 0x55) is equal true && true = 1
Upvotes: -1
Reputation: 309
C defines values greater than zero to be "True". As both 0x65 and 0x55 match this condition, the result is also True - which, on output, is 1 - or, in hex notation, 0x01.
An alternative style of writing for your code would be:
return (0x65 is true) and (0x55 is true);
Upvotes: -1
Reputation: 1224
Any expression that evaluates to 0 is false. And any expression that is non-zero is true. So both 0x65 and 0x55 are true.
0x65 && 0x55
=> true && true => true
Upvotes: 0
Reputation: 72271
&&
is a logical operator, not a bitwise operator. Both 0x65 and 0x55 are true, so the result is a true number. 0x01 is a true number.
Binary representations only come into play for bitwise operations. The expression 0x65 & 0x55
is equal to 0x45
.
Upvotes: 0
Reputation: 145829
&&
operator:
If the left operand and the right operand are both different than 0
it evaluates to 1
otherwise it evaluates to 0
.
If the left operand is 0
, the right operand is not evaluated and the result is 0
.
0x65 && 0x55
is evaluated to 1
.
Upvotes: 2