tags:

views:

184

answers:

5

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 dont remember my professor covering this, someone enlighten me please... i know the answer i get is 1, but why?

thnx

+6  A: 

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.

Prasoon Saurav
Would you care explaining "short-circuiting"?
thyrgle
See the edits (link).
Prasoon Saurav
short-circuit boolean evaluation means that if the left-hand side value is enough to determine the truth of the entire expression, then the right-hand values aren't evaluated at all. This is both an optimisation, and essential when checking say a pointer is not null on the left, then dereferencing it on the right. For || - the OR operator - if the left hand value is true then the entire expression is true, and the right-hand part unevaluated.
Tony
R..
ohh ok that makes sense, thnx a lot!
NetSkay
@R : Yes you were right, I have edited my answer for more clarity.
Prasoon Saurav
@R: was just answering thrgle's general question... no claim of relevance to the expression in the question intended. BTW - playing devil's advocate - everyone's assuming x, y, z behave like builtin types: could have an operator=(X) for some numberic type X but a operator bool() const or similar that's not intuitive. Still, question is tagged C++ and C, so can ignore C++'s user-defined-type ability... :-)
Tony
So what should be the output of 'int main(){ int x = 0, n = 0; bool b = ++x || (++n); cout << n;}'
Chubsdad
Since parenthesis has higher priority than any other operator involved in the expression, would n be 1?
Chubsdad
Prasoon Saurav
Prasoon Saurav
Oh Ok. That's what was bothering me. It's fine now
Chubsdad
(Irrelevance is also arguable... short-circuit evaluation may take more or less CPU cycles, but that's not the expressed concern in the original question....)
Tony
A: 

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

JoshD
The ! will not be evaluated first! x will be.
Jonathan Leffler
Wrong - see Prasoon's answer and consider short-circuit evaluation.
Tony
Note I said assume no short circuiting. But otherwise you are correct. I thought he might want a more thorough answer.
JoshD
@JoshD: if your compiler permits disabling short-circuiting, please, delete it.
jweyrich
@jweyrich: Indeed I would delete it. My intent was to illustrate the order of operations to a learning student.
JoshD
A: 

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.

R..
A: 

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.

PatrickV
R..
@R - Comment verified. Post updated.
PatrickV
No, the answer is always 1. The result of logical AND and OR is always an `int` with the value `0` or `1`. C++ is the same, except that the type is `bool`, which gets promoted to an `int` when passed to `printf`.
Derek Ledbetter
Now you're wrong for a new reason. The answer is always 1. Result of logical operators in C is well-defined as 0 or 1; it's not an implementation issue.
R..
@R.: the question is tagged C and C++
Jens Gustedt
@R C has a long history. Much longer than C standards. The first C compiler was out mid-70's, while the first C standard was around 89. When working with a language who's implementation far preceeded the standard, it is ALWAYS a question of implementation. The true <-> non-zero relationship is rampant in C. Feel free to go test every C compiler ever written and prove none of them worked this way - short of that - no sale. I will, however, update my post to change "C compliant" to indicate a possible return from compilers.
PatrickV
A: 

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.

Tony