Why isn't the variable being incremented? - c

Increment operator not working.
I was learning C language expressions. I've also tried different combinations of increment operators (prefix and postfix) on the variables but the output is coming out to be same.
int i=-3, j=2 ,k=0,m;
m=++i&&++j||++k;
printf("%d%d%d%d\n",i,j,k,m);
I expect the output to be -2311 but it comes out to be -2301.

i and j are incremented because i needs to be evaluated. j also needs to be evaluated because i is non-zero.
But since this combined expression is non-zero, || short-circuits, and k++ is not evaluated or executed.
On the other hand, bitwise operators don't short-circuit. They also don't convert to booleans. If you want to evaluate all conditions and keep the same result you could write
m= (!!++i) & (!!++j) | (!!++k);
using the double negation trick to convert integer value to boolean.
Or spare another statement and simplify to (courtesy from user694733):
++i; ++j; ++k;
m = i && j || k;

The && and || operators short-circuit - depending on the value of the left-hand side of the expression, the right hand side may not be evaluated at all.
For the expression a || b, if a is non-zero, then the result of a || b is 1 regardless of the value of b, so b is not evaluated. For the expression a && b, if a is zero, then the result of a && b is zero regardless of the value of b, so b is not evaluated.
In your case, the result of ++i && ++j is non-zero, so ++k is not evaluated.

Related

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

Unexpected behaviour of pre increment operator in 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.

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 ....

Evaluation of the following expression

The following code snippet:
int i=-3,j=2,k=0,m;
m=++i && ++j || ++k;
can be evaluated using two concepts,I believe:
1.Since ++ operator has greater precedence than the logical operators,so first all increment operators will be evaluted,then && having higher precedence than || will be computed.In this process,k will be incremented.
2.First && operator will be evaluated.For this ++ i and ++j will be computed.Since the result of the && operator is 1,no need to evaluate the ++k.So k will not be incremented.
When I try it on a system, the result proves reasoning 2 to be correct and 1 to be wrong. Why is it so?
Oli is right... You're confusing precedence with evaluation order.
Precedence means that the expression is interpreted as:
m = ((((++i) && (++j)) || (++k));
As opposed to, say:
m = (++(i && ++(j || (++k)))
Precedence doesn't change the fact that the LHS of the || operator will always be evaluated before the RHS.
In attempting to be efficient, evaluation of an OR statement (executed from left to right) stops when the LHS is true. There is no need to start evaluating the RHS - there is no concept of "precedence" except within the same group of an expression (when it matters to the value of the expression whether you first do A or B. Example: 5 + 3 * 2 should evaluate to 11. But in evaluating ( 5 + 6 > 3 * 2) it doesn't matter whether you do the addition before the multiplication - it doesn't change the result of the comparison. And in practice this gets evaluated left-to-right. Thus you get the result you observed.
See also this earlier answer
The && and || operators force left-to-right evaluation. So i++ is evaluated first. If the result of the expression is not 0, then the expression j++ is evaluated. If the result of i++ && j++ is not 1, then k++ is evaluated.
The && and || operators both introduce sequence points, so the side effects of the ++ operators are applied before the next expression is evaluated. Note that this is not true in general; in most circumstances, the order in which expressions are evaluated and the order in which side effects are applied is unspecified.

Require explanation for the output

Code:
#include<stdio.h>
int main()
{
int j = 7, i = 4;
j = j || ++i && printf("you can");
printf("%d %d",i,j);
return 0;
}
Output:
4 1
[Code Link][1]
The precedence of prefix operator is higher than logical operators.
2.Logical && has higher precedence than logical ||.
In Logical AND(&&) if first operand evaluates to false than second will not be evaluated and In Logical OR(||) if first operand evaluates to true, then second will not be evaluated.
The complete expression is evaluating to true, therefore j is 1 .
Doubts:
Why the first rule is not followed here? Shouldn't it be correct?
j=(j||((++i) &&printf("you can")));
Therefore value of i becomes 5, in the printf statement.
Why are the general precedence rules are violated here? Associativity comes into action when precedence of two operators is same. Shouldn't the compiler first see whether to evaluate || or &&?
If || is evaluated first, which shouldn't be as per my knowledge, then result is correct. However, if it is not evaluated first, then you can51 should be printed.
In this expression:
j = j || ++i && printf("you can");
There's a sequence point after the || and it is evaluated from left to right. Since j is non-zero, the rest of the expression is not evaluated. Hence, j || (....) becomes true which is 1. Since is ++i is not evaluated i remains 4. Hence, the output is 4, 1.
From the C standard:
Annex C
— The end of the first operand of the following operators: logical AND
&& (6.5.13); logical OR || (6.5.14); conditional ? (6.5.15); comma ,
(6.5.17).
If you j was zero then ++i && printf("you can") would have been evaluated and i would become 5 and you can will also be printed. You are correct about the precedence of ++ being greater than ||, but since there's a sequence point, j|| is evalauted first.
j || ++i && printf("you can") evaluates to true, which is represented by 1. Because it is an OR, and because j is non-zero, only the left hand of the OR is evaluated, so the ++i and the printf aren't evaluated. Thus j is 1 and i stays at 4.
Of course, real code should never every do anything like that. You should always write code in ways that the order of operations is obvious, and you should almost never have code with side effects in OR statements.
What you have here:
j = j || ++i && printf("you can");
Is a logic expression (there's no math happening). Let's break it down:
++i // as a mathematical expression this is i=i+1 (5 in your case)
printf("you can"); // printf returns the number of chars written, (7)
So you'd expect this to be:
j = 7 || 5 && 7;
The output of the above expression is simply 1. So even if this executed you should see j=1. So why don't you see the printf() output?
The reason to that is that whole expression didn't run. It doesn't have to. Consider:
result = TRUE || (anything else);
Anything that's "true" or'd with anything else will always return true. The compiler knows this and once it sees 7 || it equates that to true || and says "I know enough, set j to true and move on".
This is why the expression doesn't increment i and why it doesn't print "you can".
Now if you were to flip the expression:
j = ++i && printf("you can") || j;
The logic stays the same but the compiler doesn't see the || until it's evaluated everything else, so i will be incremented and the printf will be displayed.
I ran this program two ways:
j = j || ++i && printf("you can");
then, like this:
j = j || (++i && printf("you can"));
The output for both was 4 1. Before I ran them, I expected to get the exact same result from both due to the left to right associativity of logical or. The entire expression is gonna be evaluated from left to right regardless. The role of the parentheses is to ensure that an expression is evaluated as one expression, and doesn't necessarily mean that it will be the first expression to be evaluated. If you want more evidence of this, try something simple:
j = 1 || (++i);
Even though (++i) is in parenthesis, it is never evaluated. Again, because of left to right associativity.

Resources