-5

I have been coding from a long time though I'm still a student programmer/ I'm usually good at programming but when questions like the one below are asked I get stuck. What will be the output and why of the following program?

int main() 
    {
        int i=4,j=-1,k=0,w,x,y,z;
        w=i||j||k;
        print("%d",w);
        return 0;
    }

output: 1 why this result? what does the statement w=||j||k; means?

  • 6
    Can somebody also explain the +1 on this question? – Fiddling Bits Nov 18 '15 at 16:21
  • 2
    Why should it mean anything different than in a condition? – too honest for this site Nov 18 '15 at 16:22
  • Another way to write this would be `w = ((i != 0) || (j != 0) || (k != 0));` where I only put the brackets for clarity. Each part such as `(i != 0)` will evaluate to `0` or `1`. Remember, in a C boolean test it is implied that `0` is `false` and all other values are `true`. – Weather Vane Nov 18 '15 at 16:24
  • There are many other dups of this one on SO. You may want to read [short-circuit evaluation](https://en.wikipedia.org/wiki/Short-circuit_evaluation). – P.P Nov 18 '15 at 16:34

3 Answers3

3

i || j || k is evaluated from left to right. It does that:

i == 4, which is true, so ORing it with any other value will yield true. That's it1.

The rest of the statement is not evaluated because || and && are short-circuit operators, that is, if in your statement i != 0, neither j nor k will be evaluated because the result is guaranteed to be 1. && works similarly.
That's important to remember if you have something like f() || k(), where k has some side effect like an output to screen or a variable assignment; it might not be executed at all.

The bitwise OR operator | really ORs the bitwise representations of the values instead; it evaluates all its operands.


1 Thanks to @SouravGosh on that!

Community
  • 1
  • 1
cadaniluk
  • 15,027
  • 2
  • 39
  • 67
2

In your code,

 w=i||j||k;

is equivalent to

w= ((i||j) || k);

That means, first the (i||j) will be evaluated, and based on the result (if 0), the later part will be evaluated.

So, in your case, i being 4, (i||j) evaluates to 1 and based on the logical OR operator semantics, the later part is not evaluated and the whole expression yields 1 which is finally assigned to w.

Related quotes, from C11 standard, chapter §6.5.14, Logical OR operator

The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

then, regarding the evaluation of arguments,

[...] If the first operand compares unequal to 0, the second operand is not evaluated.

and regarding the grouping,

[...] the || operator guarantees left-to-right evaluation;

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • I did not downvote, but your answer has kind of a flaw: For `(i||j)`, `j` will not be evaluated if `i` yields _true_ already. You are basically right that this `||`-expression **will** be evaluated as such, but just not necessary both operands. – too honest for this site Nov 18 '15 at 16:50
  • @Olaf Sir, I understand your point, but I never mentioned that `j` will get evaluated in the evaluation of `(i || j)`. The logical OR will get evaluated, no? Can you suggest any better wordings? FWIW, to avoid any confusion, I have already added the related quotes from the standard. – Sourav Ghosh Nov 18 '15 at 17:00
  • To me it was ok, because I know the details. With the addition it is fine now. I too have sometimes DVs without comment. Maybe there should be an requirement to leave a comment. How else should one improve one's answer? – too honest for this site Nov 18 '15 at 17:45
0

The result of boolean operators yields an int value of 0 or 1.

See 6.5.13 and 6.5.14, paragraph 3.

The [...] operator shall yield 1 [or] 0. The result has type int.

pmg
  • 106,608
  • 13
  • 126
  • 198