Unexpected behaviour of pre increment operator in C - c

#include <stdio.h>
void main()
{
int i = -3, j=2, k=0, m;
m= ++i|| ++j && ++k;
printf("%d%d%d%d", i, j, k, m);
}
If we see order of evaluation in ++i|| ++j && ++k; we will come up with evaluation of ++j && ++k at first it will increment value of j and k and it will evaluate as 1 after that
++i || 1 will evaluate which will increment value of i and assign 1 to m so output should be -2 3 1 1 but it's giving output -2 2 0 1 I think i am missing some concept here.

|| and && are short-circuiting operators. They don't evaluate the second operand if it is not necessary to determine the output.
Here, ++i evaluates to a non-zero value, which is true in a boolean context. The right-hand side is not evaluated at all.

Since operator || and && are short circuit evaluated, once ++i is evaluated as true, ++j and ++k won't be evaluated. Thus, j and k are unchanged.

Logical operator always evaluates from left to right. These operators are known as short-circuit operator, i.e, if the value of the expression can be deduced from the value of the left operand alone, then right operand is not evaluated. Since i is non zero here, ++j && ++k is never evaluated and hence no modification is done to j and k.
Operator precedence has nothing to do with the order of evaluation. Do not get confused.

m will be equal to 1 since first , the OR condition is first evaluated, and as ++i is non-zero, you will get
m=1
as the first part of the OR statement itself is true, second part is not evaluated. So your j and k values will remain unchanged.

Related

Not getting expected output from this code using logical operators and pre/post increment

I am not getting expected output in the following C code
main(){
int i=0,j=-2,k=0,m;
if((!i||--j&&k++)&&(i++||j++&&!k++))
{
printf("i=%d j=%d k=%d",i,j,k);
}
return 0;
}
I got the output in compiler as :
i=1 j=-1 k=1
But I don't understand what exactly is going on here.
I think the if statement should not run since its argument is false
Note the first bracket (!i||--j&&k++)
here as !i=1 hence this bracket is true since anything with 1 under OR operator will be true.
out values become: i=0, j=-3, k=1
Now notice the second bracket: (i++||j++&&!k++)
Here we have ( 0 || -3 && !1) = 0, false
as the brackets are separated by &&, the whole argument of if statement becomes false.
Please explain me where my argument is wrong. I am a new to C
The logical AND operator && and the logical OR operator || are short circuit operators, meaning that the right side won't be evaluated if the result of the expression can be determined from the left side.
So when this subexpression runs:
(!i||--j&&k++)
Which is parsed as:
(!i||(--j&&k++))
The left side of the || evaluates to true, so --j&&k++ is not evaluated, meaning the value of j remains -2 and the value of k remains 0.
So the left side of the outermost && is true, so now we evaluate the right side:
(i++||j++&&!k++)
Which is parsed as:
(i++||(j++&&!k++))
i is incremented to 1, then the old value is used in ||. The old value of 0 evaluates to false so the right side is evaluated. j is incremented to -1 and the old value of -2 evaluates to true, so the right side of && is evaluated. k is incremented to 1 and the old value of 0 is applied to the ! operator which evaluates to true. This makes the entire expression true and the statement is printed, at which time i is 1, j is -1, and k is 1.
Let’s spread this out a little to make reading it easier:
int i = 0, j = -2, k=0, m;
(!i || --j && k++) && (i++ || j++ && !k++)
As you note !i is true (value 1), so the || is true. The || operator is defined not to evaluate its right operand if the left operand is true, so --j && k++ is not evaluated and has no effect. (The right operand is --j && k++ because && has higher precedence than ||, so A || B && C is structured as A || (B && C).)
That settles the left operand of the central &&. In the right operand, i++ increments i to 1 but evaluates to the current value of i, 0, so it is false for the purposes of the || operator. So the right operand of that || is evaluated.
That operand is j++ && !k++. Since j is −2, j++ changes j to −1 and evaluates to −2, which is a value of true for the purposes of &&. Then k++ increments k to 1 but evaluates to 0, and !k++ changes this to 1, yielding true for the && and therefore true for the previous || and the central &&.
At this point i is 1, j is −1, and k is 1, which is the result you got.
you may be missing that if statements ends once they are satisfied, so (!i||--j&&k++) is only going to compute i and the other operations are going to be disregarded. By that I mean j is going to be -2 by the end of the first statement.

C program logic operator sequence

why would the second line
int i=-3, j=2, k=0, m;
m = ++i && ++j || ++k;
terminate after ++j and ignore ++k ?
I know the first half make TRUE value and would return TRUE whatever the following value is. But what is the condition to stop executing following instrument? As long as we can confirm the final value?
&& has higher precedence than that of ||. ++i and ++j binds to it and
m = ++i && ++j || ++k;
is parsed as
m = (++i && ++j) || ++k;
Since both the sub-expressions ++i and ++j are non zero, it is interpreted as true. Due to short circuit behavior of logical operators second (right) sub-expression is not evaluated in case of || if left becomes true.
Note that the left sub-expression for || is (++i && ++j), not j++.
The condition is exactly that. In an OR in C, whenever the result is found to be true, none of the rest of expressions are even evaluated.
If you want to test true or false and also be sure that the variables involved are increased, you should instead increase the variables before and then test:
++i;
++j;
++k;
m = i && j || k;
The || operator does not evaluate the second operand if the first operand evaluates TRUE.
And the && operator does not evaluate the second operand if the first operand evaluates FALSE.
The operands of logical-AND and logical-OR expressions are evaluated from left to right. If the value of the first operand is sufficient to determine the result of the operation, the second operand is not evaluated. This is called "short-circuit evaluation." There is a sequence point after the first operand. See Sequence Points for more information.
Get the answer you want: here

Output of following code [duplicate]

This question already has answers here:
Why isn't "k" incremented in the statement "m = ++i && ++j || ++k" when "++i&&++j" evaluates to true? [duplicate]
(5 answers)
Closed 9 years ago.
#include<stdio.h>
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;
}
Could someone tell how does is the m evaluated. I am confused as how k remain '0'
m= ++i && ++j || ++k;
First, ++i && ++j takes effect, i become -2 and j become 3, which makes ++i && ++j non-zero, so m will be evaluated to 1 (true) because of short-circuit. All the later expression(++k) won't be executed.
m= ( (++i) && (++j) ) || ++k;
| |
| |
( T (-2) AND T(3) ) OR something
^^^^^^^^^^^^^^^^^
T OR something
^^^^^^^^^^^^^^^^^^^^^^^^^
= T
= 0
Changing j=-1
m= ( (++i) && (++j) ) || ++k;
| |
| |
( T (-2) AND T(0) ) OR something
^^^^^^^^^^^^^^^^^
F OR T (0) //++k evaluated
^^^^^^^^^^^^^^^^^^^^^^^^^
= T
= 0
Initialized Values:
int i=-3,j=2,k=0,m;
Original expression:
m= ++i && ++j || ++k;
With implicit operator precedence:
m= (++i && ++j) || ++k;
The expression evaluates left to right. What you need to understand is how Short Circuit Logic works.
Evaluation Walkthrough:
i gets incremented (-3 --> -2)
The logical AND operator is evaluated (&&). It checks if the left hand argument i evaluates to true (i!=0). If the left hand side evaluates to false, the and operator short circuits the evaluation and returns false (0). This doesn't happen because i==-2, so the right hand side (++j) is also evaluated.
j get incremented (2 --> 3)
Logical AND finishes its right hand side evaluation i!=0 && j!=0. It returns true (!0).
The logical OR operator is evaluated (||). It checks if the left hand argument (++i && ++j) evaluates to true (!0). If the left hand side evaluates to true, the and operator short circuits the evaluation and returns true (!0). This happens because ++i && ++j already evaluated true. Consequent k++ never executes!
Logical OR (||) assigns the evaluated value (!0) to m. m!=0 after the expression evaluates.
This is because of short circuting. If you know about how an OR expression is evaluated, you will get the hang of this expression. 1 OR Anything is always 1
int i=-3,j=2,k=0,m;
m= ++i && ++j || ++k;
`-2 && +3 is +1 therefore +1 OR anything is 1.` Hence C skips evaluation of k.
the answer would be
-2 3 0 1
Explanation :
There are two basic facts that work here
FACT 1 :
Whenever there is an expression with PRE-INCREMENT operator, All these operators would be operated on the corresponding variables first, and then the whole expression would be evaluated with updated values of variables.
FACT 2
whenever there is an expression having OR operator, If first operator is true(or non zero in some cases), second operator wouldn't be executed.
for example
a=2;
b=2;
c=3;
boolean k = c || a+b ;
The values of variable k would be true and the expression "a+b" wouldn't be even considered as c is non zero.
In your case variable i and j would be incremented first and the expression would be
-2 && 3 || ++k
Note : variable k wouldn't be incremented here because in case of OR logical operator Left operand would be solved completely first.
Left operand would would be then TRUE because both -2 and 3 are non zero .
so the whole expression would be
TRUE || ++k
This wouldn't be evaluated further because no matter what, the result always be TRUE .
as we are assigning this result (TRUE) to an integer variable, it would be 1.
Hence the answer is ....

How come j is not incremented in this example?

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

Post-increment and pre-increment operator in C [duplicate]

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();
}

Resources