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

phuclv
  • 37,963
  • 15
  • 156
  • 475
mayotic
  • 342
  • 1
  • 3
  • 15
  • 5
    "what will the following statement display?" Go run it yourself... yikes. If you then don't understand and want to ask "why?", *that's* a reasonable question. – Tony Delroy Sep 28 '10 at 03:13
  • i know, i did, but that doesnt explain to me the logic behind the operation :/ – mayotic Sep 28 '10 at 03:17
  • Possibly duplicate: http://stackoverflow.com/questions/3375041 – jweyrich Sep 28 '10 at 03:23
  • Possible duplicate of [Please explain an apparent conflict between precedence of && and || and the actual result of an expression](http://stackoverflow.com/questions/3375041/please-explain-an-apparent-conflict-between-precedence-of-and-and-the-actu) – phuclv Jul 30 '16 at 11:42
  • Possible duplicate of [Why does “++x || ++y && ++z” calculate “++x” first, even though operator “&&” has higher precedence than “||”](http://stackoverflow.com/q/3700352/995714) – phuclv Jul 30 '16 at 11:43

5 Answers5

3

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.

Community
  • 1
  • 1
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • Would you care explaining "short-circuiting"? –  Sep 28 '10 at 03:13
  • 2
    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 Delroy Sep 28 '10 at 03:18
  • 1
    @Tony: whether or not the right-hand part is *evaluated* is irrelevant since it has no side-effects. What matters is that `&&` has higher precedence (i.e. binds more tightly) than `||`. – R.. GitHub STOP HELPING ICE Sep 28 '10 at 03:24
  • ohh ok that makes sense, thnx a lot! – mayotic Sep 28 '10 at 03:26
  • @R : Yes you were right, I have edited my answer for more clarity. – Prasoon Saurav Sep 28 '10 at 03:28
  • @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 Delroy Sep 28 '10 at 05:53
  • So what should be the output of 'int main(){ int x = 0, n = 0; bool b = ++x || (++n); cout << n; }' – Chubsdad Sep 28 '10 at 10:49
  • Since parenthesis has higher priority than any other operator involved in the expression, would n be 1? – Chubsdad Sep 28 '10 at 10:51
  • @Chubsdad : Precedence has got nothing to do with the order of evaluation. `++x || (++n)` is similar to `++x || ++n` . The order of evaluation is well defined for operarors like `&&, || , comma `. `n` would still be 0 because evaluation of `++n` would not take place due to the short circuiting effect of `||`. – Prasoon Saurav Sep 28 '10 at 10:53
  • @Chubsdad : @R meant to say that if `||` had higher precedence then `(x || !y && z)` would have been interpreted as `( (x||!y) && z) )` which would have caused the evaluation of `z` because the first operand of `&&` would be non-zero. Since the expression had no side effects so whether the right hand side is evaluated is irrevant as @R said. – Prasoon Saurav Sep 28 '10 at 10:57
  • Oh Ok. That's what was bothering me. It's fine now – Chubsdad Sep 28 '10 at 11:00
  • (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 Delroy Sep 29 '10 at 01:32
1

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
  • 12,490
  • 3
  • 42
  • 53
0

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.

Community
  • 1
  • 1
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
-1
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.

phuclv
  • 37,963
  • 15
  • 156
  • 475
PatrickV
  • 2,057
  • 23
  • 30
  • 4
    Wrong, short-circuiting is irrelevant. That's only a matter of whether side effects occur. This is a simple operator precedence problem. If you don't believe me, try replacing `&&` with `,` (the comma operator). :-) – R.. GitHub STOP HELPING ICE Sep 28 '10 at 03:22
  • 2
    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 Sep 28 '10 at 03:53
  • 1
    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.. GitHub STOP HELPING ICE Sep 28 '10 at 03:58
  • @R.: the question is tagged C and C++ – Jens Gustedt Sep 28 '10 at 08:10
  • @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 Sep 28 '10 at 09:42
  • Why on earth no one downvotes this? How does true becomes a non-1 value? How isn't operator precedence relevant here? – phuclv Jul 30 '16 at 11:47
-2

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.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711