First, let's look at the order of operations. The logical AND operator && has higher precedence than the logcial OR operator ||, so the expression parses as follows:
c = a++ || (++b && ++c);
Next, both || and && are short circut operators. This means that the left has side is evaluated first, and if the result can be determined solely from that then the right hand side is not evaluated.
So a starts out with the value 10. a++ evaluates to the current value (10) while incrementing a as a side effect. This means the value 10 is the left hand side of ||. Because this is a non-zero value, the value of the entire expression is 1 and the right hand side ++b && ++c is not evaluated. Then this result is assigned to 1.
So the end result is a is incremented to 11, c is assigned 1 because that is the value of the || expression, and b is unchanged.
Using logical operators on integers in C - Stack Overflow
Logical Operators in C - Stack Overflow
c - Using logical operators with macros - Stack Overflow
Bitwise operators v.s. Logical operators. What's the difference?
Videos
First, let's look at the order of operations. The logical AND operator && has higher precedence than the logcial OR operator ||, so the expression parses as follows:
c = a++ || (++b && ++c);
Next, both || and && are short circut operators. This means that the left has side is evaluated first, and if the result can be determined solely from that then the right hand side is not evaluated.
So a starts out with the value 10. a++ evaluates to the current value (10) while incrementing a as a side effect. This means the value 10 is the left hand side of ||. Because this is a non-zero value, the value of the entire expression is 1 and the right hand side ++b && ++c is not evaluated. Then this result is assigned to 1.
So the end result is a is incremented to 11, c is assigned 1 because that is the value of the || expression, and b is unchanged.
This expression
c = a++ || ++b && ++c;
can be equivalently rewritten like
c = ( a++ ) || ( ++b && ++c );
As the expression a++ is not equal to 0 then the second sub-expression ( ++b && ++c ) is not evaluated.
The value of the logical operator || and && is either 1 (true) or 0.
From the C Standard (6.5.14 Logical OR operator)
3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
and
4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.
So c gets the value 1 and a was increased.
&& 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.
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.
Besides #ifdef, the preprocessor supports the more general #if instruction; actually, #ifdef MACRO is a shortcut for #if defined(MACRO), where defined is a "preprocessor function" that returns 1 if the macro is defined; so, you can do:
#if defined(MACRO1) || defined(MACRO2)
void foo()
{
}
#endif
#if defined(MACRO1) || defined(MACRO2)