Confusion with post increment and logical operator? - c

#include <stdio.h>
#include <string.h>
main()
{
int i=-1, j=-1, k=0, l=2,m;
m = i++&&j++&&k++||l++;
printf("%d%d%d%d%d", i, j, k, l, m);
}
Output:
00131
I am confused how the expression is getting evaluated.

All that really matters here is the ||. Since l++ evaluates to the boolean 1 (true), the entire statement is true. So m is 1, and the rest are just their original values plus one for the post increment after they are evaluated.
You're evaluating the boolean expression:
((-1 && -1) && 0) || 2
As an aside, your definition of main should be:
int main(void)

I presume your question is about which increments will actually occur.
&& and || (logical and and logical or) are "short-circuit" operations. They evaluate only enough of their arguments to determine whether they're true or false. Effectively, x && y can be treated as x ? y : 0 and x || y can be treated as x ? 1 : y
&& takes precedence over ||, so start by looking at i++ && j++ && k++. This starts by evaluating i++, returning -1 and setting i to 0. Since the returned value is true (nonzero), we continue by evaluating j++, which once again returns -1 (true) and increments j to 0. We still haven't proven the value of the &&, so we evaluate k++, which returns 0 (false) and increments k to 1. That false gives us a final anded value of false.
Now we proceed to the ||. Effectively, you now have false || l++. The false is not enough to determine the result of the or, so we evaluate l++. That returns 2 (true), while setting l to 3. That true forces the value of the ||, and the final value of the expression, to be true.
Note that if i, j, or k had started as 0 (false), the later increments would not have occurred, since short-circuit evaluation would have decided they weren't needed in order to produce a result. In general, mixing && or || with side effects is a bad idea for exactly this reason -- it produces logic that is needlessly hard to understand. The ?: versions -- or a real if/then/else statement -- would make this interaction much, much clearer. You should understand how to read this sort of mess, because you will run into it in other programmers' C code -- but you should almost never write it. And if you must, you should document it to death. The sanity you save may be your own.

use this rules:
i++ =post increments the value of i, k++ =post increments the value of k, l++ =post increments the value of l, j++ =post increments the value of j
&& - if values compared are both nonzero true(1) otherwise false(0)
|| - if values compared are both zero false(0) otherwise true(1)
then apply towards expression m (also read on operator precedence in c)

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.

Why isn't the variable being incremented?

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.

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.

Logical operator with Arithmetic operator in C

I came across a question and I wanted to verify whether my assumptions were correct.
Given the following codes:
1. int i = -2, j = 1, ans;
2. ans = i++ || ++j;
3. printf("%d %d %d", i,j, ans);
The output is: -1 1 1
In C language, it seems that only 0 will be treated as false, any other values will be treated as true when used with a logical operator. So I am not doubtful why ans derives to 1 (true || true gives us true(1) )
What I wanted to ask here is: Why is the value of j still 1 and not 2 despite ++j?
Can safely assume that any arithmetic operations after the logical operators || && will only be effective at the line it is used(in this case, line 2), and after which the variable still retain its original value?
|| operator wont do any operation on second operand when first operand is nonzero.
Because, any one of the operand is non-zero then, output will be true in || operator operation. In your code 1st operand is non-zero. Thats why operation on second operand is not performed.
As in Second Line of your Code i.e
ans = i++ || ++j;
first it will check i++ as it is not zero that means it is true.
And in OR Condition if first condition is true it will not check second condition i.e ++j.
Because if first condition is true is doesn't matter, Second condition is TRUE or FALSE it will return a true value. So if First Condition is true it will not check the other condition.
Logical operators short circuit. That is, in the following:
ans = i++ || ++j;
++j will never be evaluated if i++ evaluates to true (non-zero).

OR and AND operation in C

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.

Resources