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.
Related
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.
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.
C newbie here, and I'm wondering, how come j is not incremented in the example below?
I searched everywhere for an explanation
int i, j, k;
i = 3; j=4; k=5;
_Bool checkbit;
checkbit = i < j || ++j < k;
printf("%d\n", checkbit );
printf("%d %d %d\n", i, j , k);
The output is
1
3 4 5
instead of
1
3 5 5
Thanks!
Because it doesn't need to be evaluated.
checkbit = i < j || ++j < k;
i < j will yield true, so no matter what the second part of the expression yields, the value of checkbit will be true. Thus, it doesn't even bother evaluating it.
Just for kicks:
checkbit = i > j && ++j < k;
In this case, the second expression will not be evaluated because false && (expr) is false.
Double-Or is "Shortcutting" - it won't evaluate the rest of the expression if the first part is true.
Use a single-or to increment it whatever happens.
This can be useful sometimes. It speeds up execution, because if the first part is true, you know the result of the or must be true!
Note that this is the same (in reverse) for &&: If the first part of && is false, then the second part is ignored, as you know the result will be false.
And it's perhaps worth mentioning that this behavior, short-circuit evaluation, is in the C standard:
6.5.14 Logical OR operator
Syntax
1 logical-OR-expression:
logical-AND-expression
logical-OR-expression || logical-AND-expression
Constraints
2 Each of the operands shall have scalar type.
Semantics
3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it
yields 0. The result has type int.
4 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.
(emphasis mine)
When using || operator, and the first condition evaluates to true, it ignores the rest unlike the && operator
checkbit = i < j || ++j < k; //since i < j is true, it skips over ++j < k
This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 5 years ago.
Why is k not getting incremented whereas,i and j are getting incremented in the same expression.And i also want to know what is the output of the program.I am getting the output as
-2 3 1 0
#include <stdio.h>
void main()
{
int i=-3, j=2, m, k=0;
m=++i && ++j || ++k;
printf("%d %d %d %d", i, j, m, k);
}
The logical or, || short-circuits, and after
++i && ++j
the value of the entire expression is determined, so the right operand of the || isn't evaluated.
m=++i && ++j || ++k;
is parenthesized m = (++i && ++j) || ++k; since the && has higher precedence than the ||.
The short-circuiting of the logical operators means that the right operand is only evaluated when the evaluation of the left has not yet determined the final result, for || that means the right operand is only evaluated if the left evaluated to 0, and for &&, the right operand is only evaluated if the left evaluated to a nonzero value.
So first ++i && ++j is evaluated, and for that, first ++i is evaluated. i had the value -3 before, so ++i evaluates to -2, which is not 0, hence the ++j is evaluated too. j had the value 2 before, so ++j evaluates to 3, which is again nonzero, and thus ++i && ++j evaluates to 1 (true). Since the left operand of the || is not zero, its result is already determined (to be 1), and the right operand isn't evaluated, thus k remains unchanged and m is set to 1.
If the item on the left of an || condition evaluates to true, there is no point evaluating the right hand side since the OR condition is already satisfied. That is why the ++k is not being evaluated
These operators are known to be short-circuited operators. So, if the expression ++i && ++j is true, it does not evaluate k (we know the value of the expression regardless to the value of k).
It has to do with order precedence. Anytime a logical OR is executed, it will stop if the first operand is true, which in this case is j.
The logical operator || works like this: if first condition is true then the second one is not evaluated.
So first (++i && ++j) checks. It returns true, so after it || is not evaluated. Thus, the value of k is not increased.
#include<stdio.h>
int add(int);
void main()
{
int i=3,k,l;
clrscr();
k= add(++i);
l=add(i++);
printf("i=%d k= %d l=%d",i,k,l);
getch();
}
int add(int ii)
{
++ii;
return(ii);
}
/*th eoutput is
5
5
5 can anyone expalin how? */
#include"stdio.h"
#include"conio.h"
main()
{
int rmv=10,vivek=10;
clrscr();
rmv++;//this post incremant means incremant next step 10+1
//rmv+1 and rmv++ both are same
printf("1.rmv++=%d\n",rmv);//value is 10
printf("2.rmv++=%d\n",rmv++);//the value is increment 11
++vivek;//this pre increment means first increment the value so,1+10=11
printf("1.\t++vivek=%d\n",vivek);////++vivek and 1+vivek both are same
printf("2.\t ++vivek=%d",++vivek");
getch();
}
I have a doubt in the program below.
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;
}
I get the output as -2 2 0 1.
In OR operation if 1st value is true then it won't evaluate the 2nd one so i = -2 and j =2.
Then comes the AND operation . It will check for both the value to be true.So if k = 1 then m = 1.
So the output should be -2 2 1 1. I run and check and got output as -2 2 0 1 but I could not understand how.
You used a short circuit or. Since ++i evaluates to -2, which is not 0, it short circuits and doesn't evaluate the rest of the expression. As a result, neither j or k get incremented.
Also note that the short circuit operators, || and &&, are left associative and that || is higher precedence than &&. As a result, the || gets evaluated first, and early outs if the left hand side evaluates to true, while && early outs if the left hand side evaluates to false.
EDIT: Fixed a mistake with explaining the precedence.
Nothing after the || is evaluated, since the result of the expression ++i is nonzero.