Given that x = 2, y = 1, and z = 0, what will the following statement display?
printf("answer = %d\n", (x || !y && z));
It was on a quiz and I got it wrong, I don't remember my professor covering this, someone enlighten me please... I know the answer I get is 1, but why?
The expression is interpreted as x || (!y &&z)(check out the precedence of the operators ||, ! and &&.
|| is a short-circuiting operator. If the left operand is true (in case of ||) the right side operand need not be evaluated.
In your case x is true, so being a boolean expression the result would be 1.
EDIT.
The order of evaluation of && and || is guaranteed to be from left to right.
If I'm not mistaken, it will print 1. (Let's assume short circuiting is off)
(x || !y && z) or (true || !true && false) will first evaluate the ! operator giving (true || false && false)
Then the &&: (true || false)
Then || : true
Printf will interpret true in decimal as 1. So it will print answer = 1\n
Given that x = 2, y = 1, and z = 0,
what will the following statement
display?
printf("answer = %d\n", (x || !y && z));
Ok - feeling a bit guilty for the harsh quip re poor wording of the question, so I'll try to help you in a different way to the other answers... :-)
When you've a question like this, break it down into manageable chunks.
Try:
int x = 2, y = 1, z = 0;
printf("true == %d\n", 10 > 2); // prints "1"
printf("false == %d\n", 1 == 2); // prints "0"
printf("!y == %d\n", !y); // prints "0"
printf("(x || !y) == %d\n", x || !y); // "1" - SEE COMMENTS BELOW
printf("(!y || z) == %d\n", !y || z); // "0"
printf("(x || !y && z) == %d\n", x || !y && z); // "1"
In the output there, you've got everything you need to deduce what's happening:
true == 1 reveals how C/C++ convert truthful boolean expressions to the integral value 1 for printf, irrespective of the values appearing in the boolean expression
false == 0 reveals how C/C++ converts false expressions to "0"
(!y) == 0 because ! is the logical not operator, and C/C++ consider 0 to be the only integral value corresponding to false, while all others are true, so !1 == !true == false == 0
(x || !y) == 1, and you know !y is 0, so substituting known values and simplifying: (2 || 0) == 1 is equivalent to (true or false) == true... that's understandable as a logical rule
(!y || z) == 0 - substituting known values: (0 || 0) == (false or false) == false == 0
(x || !y && z) == 1: here's the crunch! From above, we know:
x || !y is 1/true, which if relevant would imply 1/true && z/0/false == 1/true <- this clearly doesn't make any sense, so it must not be the way C/C++ are calculating the answer!
(!y && z) is false, which if relevant would imply x/2/true || false == 1/true <- this is true, so it must be the implicit order.
In this way, we've derived the operator precedence - the order of evaluation of the || and && operators, from the results that the compiler is displaying, and seen that if and only if && is valuated before || then we can make some sense of the results.
answer = 1
or maybe:
answer = -27
2 || !1 && 0
2 || 0 && 0
2 || 0
true
true = non-zero value
printf("answer = %d",*true*); -> who knows
Most compilers will output answer = 1. I wouldn't confidently state that all compilers will do that though, but I am confident all compilers would return non-zero.
I'm not going to give you the outright answer because you could just compile it and run it, but the question is just testing to see if you know operator precedence.
Related
Similar question to:
How is the comma operator being used here?
BOOL bShowLoadingIcon = FALSE;
if (sCurrentLevelId_5C3030 == 0 || sCurrentLevelId_5C3030 == 16 || (bShowLoadingIcon = TRUE, sCurrentLevelId_5C3030 == -1))
{
bShowLoadingIcon = FALSE;
}
In the above code sample what values/range of sCurrentLevelId_5C3030 would cause bShowLoadingIcon to be set to TRUE. Is it possible it would be set to TRUE and also become true (overall if expression) thus also then being set back to FALSE?
I have no idea what (bShowLoadingIcon = TRUE, sCurrentLevelId_5C3030 == -1) is actually doing.
C++ only evaluates a boolean OR if it needs to. So if sCurrentLevelId_5C30303 is 0 or 16, the last statement never gets evaluated.
If (bShowLoadingIcon = TRUE, sCurrentLevelId_5C3030 == -1) does get evaluated, it first sets bShowLoadingIcon to TRUE and then evaluates to the result of sCurrentLevelId_5C3030 == -1. If that's true, then bShowLoadingIcon will just get set back to FALSE.
So in summary, bShowLoadingIcon is set to FALSE. Then if sCurrentLevelId_5C3030 is neither 0 nor 16, then bShowLoadingIcon is set to TRUE, only to be set back to false if sCurrentLevelId_5C3030 is -1.
So, in even more summary, bShowLoadingIcon is set to TRUE if sCurrentLevelId_5C3030 is neither 0 nor 16 and stays that way so long as sCurrentLevelId_5C303030 is not -1.
It's equivalent to:
BOOL bShowLoadingIcon = (
(sCurrentLevelId_5C3030 != 0) &&
(sCurrentLevelId_5C3030 != 16) &&
(sCurrentLevelId_5C3030 != -1)) ? TRUE : FALSE:
Or, if you prefer:
BOOL bShowLoadingIcon = (
(sCurrentLevelId_5C3030 == 0) ||
(sCurrentLevelId_5C3030 == 16) ||
(sCurrentLevelId_5C3030 == -1)) ? FALSE : TRUE;
In C++, the comma operator (statementX, statementY) first executes statementX, and then statementY. The expression holds the value of the second statement.
In your code, bShowLoadingIcon is assigned the value TRUE, and then the value that C++ checks for in the if statement is whether sCurrentLevelId_5C3030 == -1.
I have an enum with 3 values:
enum InputState { Pressed, Released, Held };
And I'm using it in this code:
//GetState returns an InputState
if(myInput.GetState(keyCode) == InputState::Pressed)
{
//This means "keyCode" has the state "Pressed"
}
Why doesn't this work?
if(myInput.GetState(keyCode) == (InputState::Pressed || InputState::Held))
{
//This is always false
}
if((myInput.GetState(keyCode) == InputState::Pressed) || (myInput.GetState(keyCode) == InputState::Held))
{
//This works as intended, triggers when "keyCode" is either Pressed OR Held
}
As a test, I did:
//Using the same values from the enum, but as int now
if(1 == (1 || 2))
{
//This works as intended
}
Am I missing something?
|| is a binary operation that expects two boolean values. In your example, the boolean values are the result of testing for equality with ==.
To see why your simplified example works, let's evaluate the expression
1 == (1 || 2)
We must start inside the parentheses first, so we are going to first evaluate (1 || 2). In C++, any non-zero value is equivalent to true when it is used in a boolean expression, so (1 || 2) is equivalent to (true || true) which evaluates to true. So now our expression is
1 == true
Again, 1 is equivalent to true in this context, so this comparison is the same as true == true, which of course evaluates to true.
Yes, you are missing something. This worked by total accident:
(1 == (1 || 2))
It is NOT set comparison. It simply calculated (1 || 2) as true, then converted true to its integral value (1).
The same thing would have happened with
(1 == (1 || 4))
(1 == (0 || 1))
(1 == (0 || 4))
and they all are true.
But
(2 == (1 || 2))
is false.
Is this:
if(x == a || b){//do something}
same as:
if(x == a || x == b){//do something}
?
I think it is not, because in the first case we evaluate if x equals a and if b is true or false.
In the second case, we evaluate if x equals a and if x equals b. And I understand that in the lazy evaluation if x equals a than we are not evaluating further.
But somebody thinks that in the first case we ask if x equals a or b, so I wanna make sure.
No.
In C++, this:
x == a || b // Same as (x == a) || b
Is equivalent to this:
(x == a) || (bool)b
Which evaluates to true if x and a are equal OR if b evaluates to true when converted to bool. In C, on the other hand, it is equivalent to this:
(x == a) || (b != 0)
Which evaluate to true if x and a are equal OR if b is different from 0 (here we must make the implicit assumption that b is of integral type, otherwise this won't compile).
On the other hand, this:
(x == a || x == b) // Same as ((x == a) || (x == b))
Evaluates to true when either x and a are equal OR x and b are equal (i.e., if x is either equal to a or equal to b) both in C++ and in C.
The two expressions are not equivalent. This
if(x == a || b)
is the equivalent of
if( (x == a) || (b))
i.e an OR of x==a and b. In C++, if b evaluates to anything other than 0 or false, it is taken as true.
The second one tests whether x==b instead of simply testing b.
No. In C this is equivalent to:
if(x == a || b != 0)
The first reads as "if x is equal to a, or if b is truthy"
The second reads as "if x is equal to a, or if x is equal to b"
No.
if (x == a || b)
is equal to
if ((x == a) || (bool)b)
because operator == has higher precedence than operator ||. See Operator Precedence Table.
You are almost right, the first case means x equals a OR b is true.
Lazy evaluation means that the expression will be evaluated only until the result is obvious. In an OR expression, for example (x || y), the result will be known when x==true – then the whole expression must be true too. In the case of AND, like (x && y), the result will be evident when x==false. So you are right, if x==a, we know the answer already and no more work is needed.
Why is:
if(x!=y!=z)
handled as:
x=1
y=1
z=2
??
I just noticed it today.
x != y and x == y return booleans.
You're comparing z to those booleans.
Neither of them will work they way you want them to.
It probably is parsed as if ((x!=y) !=z) which does not do what you think if (x!=y!=z) should do (but does not).
Likewise if (x==y==z) probably means if ((x==y)==z) to the compiler which is not what you want.
Enable the warnings given by your compiler. With GCC, that means gcc -Wall and it would tell you warning: suggest parentheses around comparison in operand of '=='
Recall that a boolean expression like x==y gives a zero (when false) or non-zero (when true) result. Writing ((x==y) + (z==t)) is very poor taste, but makes sense for the compiler.
x == y == z is equivalent to (x == y) == z. In this case, (1 == 1) == 2, or true == 2, which is false because true == 1, not 2.
x != y != z is equivalent to (x != y) != z. In this case, (1 != 1) != 2, or false != 2, which is true because false == 0, not 2.
C(++) relational operators aren't chained like in Python. If you want to check whether three numbers are all equal to each other, use (x == y) && (y == z).
if(x==y==z)
will not work untill the value u will use for z be 1 or 0 but u can take the value of x and y anything
As when u try with the value 1 or 0 then the if will take its parameters as
if((x==y)==z)
this is happening because it first evaluate whatever the value in x and y and the answer will be in boolean and then it checks with z which it expects to be boolean. so if (x==y) be and z is 1(true) then code will be executed else it wont.Same thing will happen with (x!=y!=z). try with z=1 or 0 and x,y be anything.
Confused about if condition, how does it executes following statements.
if(1 && (1 || 0) != 0) or if(1 || (1 && 0) != 0)
In above if statement what is the sequence of executing/validating the statements.
(left to right or right to left) if left to right, then if first argument/expression is true does it evaluates 2nd expression/argument? is it true for both the logical AND and OR operators.
Thanks.
Logical && short circuits if the first operand evaluates to false (because false && x is false for all x)
Logical || short circuits if the first operand evaluates to true (because true || x is true for all x)
They both evaluate left-to-right.
It's left to right
First executes 1. Then executes (1 || 0) != 0. To do that it executes 1 || 0 -> true, so the whole thing is true.
First executes 1 - it's true, so it short circuits and returns true.
It's left to right. || short-circuits if first expression is true, && if first expression is false.
Both things are fundamentally different go read D Morgans Laws!s
lets break it down step-by-step:
(1 || 0) becomes true as 1 short-circuits the expression
so (1 || 0) != 0 is true
1 && true is true by the definition of the logical && operator
or is a define/keyword for || but the first section is already true, so we short-circuit the expression again and the code inside the if block is executed.