C: What does if(a<b<c) do? [duplicate] - c

This question already has answers here:
Comparing a variable to a range of values
(7 answers)
Closed 4 years ago.
why does the following if-statement return 1 (true)?
int main() {
short a = 1;
short b = 5;
short c = 4;
if (a<b<c)
printf("true \n");
else
printf("false \n");
return 0;
}
It is obviously not the same as
if(a<b && b<c)
because this returns false.
Thank you

The relational operators (<, <=, >, >=) are read from left to right (and have the same precedence) as you can see here: Operator precedence. Therefore
a < b
is evaluated first. The result of this evaluation (true or false then) will take part in the next evaluation
(1 or 0) < c
Essentially your code is the same as
if ((a<b)<c)

The < operator has left-to-right associativity. So your expression is parsed as follows:
(a<b)<c
So a<b is first evaluated. Since a is less that b it evaluates to true, i.e. 1. So now you have:
1<c
Since c is 4 this is also true, so the final result is 1.

The a<b statement is equal to true or 1. so we can say a<b or 1 is less than c.
printf(a<b); // result is 1
printf(1 < c) // result is true because 1 is less than 4
So this statement (a<b<c) is true
try online

Related

Logical operator | | in C [duplicate]

This question already has answers here:
What is short-circuit evaluation in C?
(3 answers)
Closed 1 year ago.
I'm struggling to understand the behavior of the below code:
#include <stdio.h>
int main(void)
{
int i;
int j;
int k;
i = 7;
j = 8;
k = 9;
printf("%d\n", (i = j) || (j = k));
printf("%d, %d, %d\n", i, j, k);
return (0);
}
Output:
1
8, 8, 9
Question:
I understand that expr1 | | expr2 has the value 1 if either expr1 or expr2(or both)has a nonzero value.
The value of i increased from 7 to 8 because j's value is assigned to i but the same way why does the value of the j is not increased even though j = k? I was expecting an
output
1
8, 9, 9
From the C standard (emphasis mine):
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.
The above behaviour is commonly referred to as operator short circuiting.
In your example, since (i = j) is not zero the second operand is thus not evaluated.
First of all,
true || true is true
true || false is true
false || true is true
false || false is false
So operator || is calculating the first expression and if it is true, it does not check the second one.
In yours particular situation (i = j) is equal to 8, which is considered true, because int values are considered false only if they are equal 0.
So the second (j = k) is never computed, which leads to your result.

Not understanding the line of statement [duplicate]

This question already has answers here:
Logical Operators and increment operators [duplicate]
(1 answer)
Logical Operators in C
(8 answers)
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 4 years ago.
Here is the code
int main()
{
int i=-3, j=2, k=0, m;
m = ++i||++j&&++k;
printf("%d, %d, %d, %d\n", i, j, k, m);
return 0;
}
And output:
-2, 2, 0, 1
But i don't understand the line m = ++i||++j&&++k; How it get's executed.
Someone please explain..Thanks!
Initially you have the 4 variables:
i = -3
j = 2
k = 0
m is uninitialized
m = ++i||++j&&++k; is executed left to right. so first one is ++i - I suggest reading about the differences between i++ and ++i - In this case i is increased by 1 and become i=-2
-2 is a true expression, therefore m becomes 1 and the rest of the expression is not evaluated. Because true or anything else is always true anyway.
So final outcome:
i = -2 (increased)
j = 2 (unchanged)
k = 0 (unchanged)
m is 1 (true)
Logical OR operation (expr1 || expr2) employs short-circuiting behavior. That is, expr2 is not evaluated if expr1 is logical 1 (true).
The expression with logical OR operator evaluate to true if any of the two operands is non-zero.
In this expression:
m = ++i||++j&&++k;
|_| |______|
LHS RHS
The i is initialized with -3. ++i will evaluate to -2.
-2 is a non zero value hence evaluate to logical true and the RHS part of the expression will not evaluated.
Since the whole expression evaluated to true, the value 1 is assigned to m.

What is the order of evaluation of the statements in this code?

I came across this question.
#include <stdio.h>
int main()
{
int k=8;
int x=0==1||k++;
printf("%d %d",x,k);
return 0;
}
The output is 1 9.
As this answer suggests that
Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.
I am unable to understand how the statement int x=0==1||k++ is evaluated,due to which the value of x and k becomes 1,9 respectively.
Can someone explain how such statements are evaluated by the compiler in c ?
"Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated."
yes it's true ...
to make it clear first make sure that you are aware of these basics
1) (1 || any_var) is 1
2) Operator precedence is as follows
++
then
==
then
||
NOW coming to your doubt of || vs |
note that | (single pipe) operator ..,will execute both LHS and RHS , no matter what)
whereas
|| (double pipe) evaluates LHS of || first and if it is 1 it need not evaluate RHS (for speed)
RHS of || operator will not be evaluted if LHS comes out to be true.
but here 0==1 is false i.e 0==1 returns 0
hence RHS will be evalauted
so the statement
k++ is executed
but 8 is used (as property of post increment operator says--> first use then increment)
so 0||8 is definitely true (1) so x evaluates to 1
and then k is incremented after sequence point ie k is made equal to 9
hence output x=1 and k=9
I hope it clears your doubt :)
The Operator || (OR) evaluates to true in the cases:
ex: A || B
A is true,
B is true,
Both are true
Because this operation uses Short-Circuit Evaluation if A is evaluated to true, it means that the statement is true already and it won't evaluate B.
In your case 0==1 (0 equals 1) is clearly false, so it will evaluate k++. k++ is a tricky one (in my opinion). In the world of C true/false evaluation is based on being 0 or not (except for the times false means less than 0...) but in true/false evaluation 0 is false, everything else is true.
K++ means evaluate K then increment, so, if K is 0 it will be false and become 1, if it is anything else, it will be true and then increment.
In your case k == 8 so the result of k++ is TRUE and k will become 9. K being true means x evaluation resulted in TRUE (it was FALSE OR TRUE).
So the output is 1(True) 9(8++)
x is 1 because the expression: 0==1||k++ turns out to be true (which is 1 in C land). Why you ask? There are two sequence points here: 0 == 1 and k++. Since the first sequence point evaluates to false (0 in C land), the second sequence point is evaluated (because the short circuit operator is ||). The second sequence returns true (or 1). So, you the entire expression breaks down to: 0 || 1. Hence x is 1.
k is 9 because of k++;
HTH.

Increment and logical operators precedence [duplicate]

This question already has answers here:
Short circuit behavior of logical expressions in C in this example
(1 answer)
Operator Precedence vs Order of Evaluation
(6 answers)
Closed 7 years ago.
In the program shown below, prefix should be evaluated first because it has higher precedence, But answer is -2, 2, 0, 1 and it is explained in book "as LHS of || is true RHS is not evaluated."
Why is it so? All the increments should performed first and then logical should be checked because of precedence.
#include<stdio.h>
int main()
{
int i=-3, j=2, k=0, m;
m = ++i || ++j && ++k;
printf("%d, %d, %d, %d\n", i, j, k, m);
return 0;
}
Don't get confused with Precedence and Order of evaluation.
The order of evaluation of logical OR || is left to right.
So if left = true then left || right will never execute right. In your code exactly same happened.
As you know, any non zero value treated as true in C, hence, ++i or -2 is true. So,
m = ++i || ++j && ++k;
m = true || bla bla bla; //right not even checked!
m = true
m = 1
And you get the output as expected.
The logical && and || operators fully evaluate the LHS before doing any evaluation of the RHS.
In the code shown, since ++i is -2, the LHS of the || evaluates to true (1) and the RHS is not evaluated. Therefore, neither j nor k is incremented. The printed result follows: m was assigned 1, i became -2, and j stayed as 2 and k stayed as 0.
The only remaining issue is that && binds tighter than ||, so:
a || b && c
is equivalent to:
a || (b && c)
so if a evaluates to true (non-zero), then neither b nor c is evaluated.
Operator precedence is a completely different thing. Order of evaluation is determined by side effects and sequence points.
see this manual on order of evaluation.

Why lower precedence operator executes first? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Problem with operator precedence
we know that precedence of prefix is greater than "LOGICAL AND" (&&) and precedence of "LOGICAL AND" is greater than "LOGICAL OR" (||).
Below program seems to violate it:
int main()
{
int i=-3,j=2,k=0,m;
m=++i||++j&&++k;
printf("%d %d %d %d",i,j,k,m);
return 0;
}
If precedence of ++ is more than && and || then all prefix should execute first. After this i=-2,j=3,k=1 and then && will execute first.
why output shows : -2 2 0 1 ?
The behavior of the program is also same on ubuntu v12.04.
The && and || operators are "short-circuiting". That is, if the value on the left is FALSE for && or TRUE for || then the expression on the right is not executed (since it's not needed to determine the value of the overall expression).
It's correct because Short-circuiting definition.
m = ++i||++j&&++k
First, left part ++i is always TRUE so now i is -2 and it doesn't execute the right part of expression, the value of j,k don't change.

Resources