Assignment operators in if statement - c

int a = 0, b = 0, c = -1;
if (b = a || b == ++c )
a+=3;
Why are the values of a,b and c 3 , 1, 0 respectively? More specifically, why is b 1 and not 0?

Because || has higher precedence than =, so it's being parsed as if you'd written.
if (b = (a || (b == ++c)))
This calculates a || (b == ++c). This is true because b == 0 and ++c == 0, so b == ++c is true, and true is 1.
Add parentheses to get what you want:
if ((b = a) || (b == ++c))
But IMHO it's generally best to avoid writing such complex expressions. Do them as separate statements:
b = a;
if (b || b == ++c)

Once you are clear with the precedence of operators,it will be easy for you to tackle such type of questions.Go through this to know about operator precedence in C.
You should see my answer after going through the precedence list because then it will get more easily inside your mind.
Now,coming to your question....
Out of all the operators used in the above code, ++c has the highest precedence.So the value of c becomes 0 and then value of c is compared to value of b here b == ++c which evaluates to true i.e 1 and now || of 1 and a is taken which is 1.
And finally this result 1 is assigned to b.So the overall execution of if statement evaluates to true and value of a is incremented by 3.
Hence finally the value of a=3,b=1 and c=0.

Related

inner short circuit evaluation in c

I know that Java and C/C++ have short circuit evaluation, i.e., in if (a && b), b will never evaluated if a is not true.
But what if I have expression like if ( (a && b) OP c ) (where OP is an arbitrary logical operator), will b evaluated if a = false? Thanks.
C Standards say that -
6.5.13 Logical AND operator
The && operator guarantees left-to-right evaluation......
.If the first operand compares equal to 0, the second operand is not evaluated.
So in case a==flase b will not be evaluated.
You will always have if a = false : a && b == 0 whatever the value of b. Why would an operation done after the evaluation will change that ?
a b | a && b
0 0 | 0
0 1 | 0
If a=false then condition for b will not be checked so (a && b) is ALWAYS false
and the next condition depends upon the OP used if it is && it will not be evaluated. If it is || it will be evaluated.
So
((a && b) OP c)
here if a=false (a && b) will be always false.

Why does the value of c not change?

#include <stdio.h>
void main()
{
int a = 5, b = -7, c = 0, d;
d = ++a && ++b || ++c;
printf("\n %d,%d,%d,%d", a, b, c, d);
}
In the above code, the output is 6,-6,0,1. Why is the value of c 0 and the value of d 1?
how did d get the value as 1?
That is because || first checks the left part and if it is true it return true without evaluating the right part.
In C any non zero is treated as True and zero as False
int a = 5, b = -7, c = 0, d;
d = ++a && ++b || ++c;
Here ++a and ++b are non zero and both are treated as True so ++a&&++b becomes True and the expression stops evaluating over there.
There are already good answers that explain why c is 0 after the line
d = ++a && ++b || ++c;
is executed.
The line is equivalent to:
d = (++a && ++b || ++c);
That explains why d is 1.
int a = 5, b = -7, c = 0, d;
d = ++a && ++b || ++c;
let's analyze the statement part by part
++a : a=6
++a && ++b: b becomes -6 ,and then it does : 6 && -6 ,which is equal to 1
now there is a || (or symbol) ,but this cannot affect the value of d since
1||"value2" =1 ,
so the compiler does not evaluate "++c" .
so c remains 0 and d becomes 6 && -6 =1
&& has higher precedence than || so first ++a&&++b is evaluated first and it becomes true. The expression becomes true || ++c and || will evaluate from left to right since || encounters true and it returns 1 to d without evaluating ++c. So c value will not be incremented
An evaluation tree is created which does the evaluation. The || part is parent and the two parts on its side are its parents. When it evaluates one child, if it gets true, it doesn't evaluate the other child.

Shortcircuiting of AND in case of increment / decrement operator

In the code below:
#include <stdio.h>
int main()
{
int a = 1;
int b = 1;
int c = a || --b;
int d = a-- && --b;
printf("a = %d, b = %d, c = %d, d = %d", a, b, c, d);
return 0;
}
i was expecting the output to be:
a=0,b=1,c=1,d=0
because due to short circuiting in the line below, ie a-- returns 0 so the other part wont get executed right?
int d = a-- && --b;
The output is:
a = 0, b = 0, c = 1, d = 0
can anyone please explain?
In first case
int c = a || --b;
After this a=1 , b=1 and c=1
a value is 1 , because of short circuit evaluation --b did not performed
int d = a-- && --b;
a-- is post decrement so decrement of a won't effect in expression
where as --b is pre decrement so effects here
Your condition becomes
int d= 1 && 0 ;
After this a=0; , b=0,c=1 and d=0.
int c = a || --b;
In this line, the C standard requires the C implementation to evaluate a first and, if it is not zero, not to evaluate --b. Although -- has higher precedence than ||, that just means that -- is grouped with b for the purposes of determining the structure of the expression, not for purposes of evaluating it. The left side of an || operator must be evaluated before the right side and, if the left side is true, the right side must not be evaluated, even in part.
So, after the above, b is not changed; it is still 1.
int d = a-- && --b;
As with ||, the left-hand side of the && is evaluated first. So a-- is evaluated. This changes a to 0. However, the value of a-- is a before the change, so it is 1. A value of 0 would prevent the right side from being evaluated (because, once we know the left side is zero, we know the value of the complete && expression is zero). But, since the left side is not zero, --b must be evaluated to finish the &&. This changes b to 0. “Short-circuiting” means the left side is evaluated first, but the right side is still evaluated when necessary.
In the first or operation, --b is not executed since a equals 1:
int c = a || --b;
But b is decremented here:
int d = a-- && --b;
Because a equals 1 and is decremented after it is evaluated (a-- equals 1). In other words, this line is similar to:
int d = 1 && --b;
b was equal to 1 so now b equals 0 now. And d also equals 0 because --b returns 0.
the line below, ie a-- returns 0
No, it doesn't. It yields 1, as the post-decrement operator evaluates to the unmodified value of the variable. What you are thinking about is perhaps --a.
c = a || --b
so at first a is evaluated and a value is 1 which is true. So compiler does not evaluate --b. So b value is still 1
Now
d = a-- && --b
a-- && --b => 1 && 0 (since --b = 0 ) since b value is at 1.
why 1 because a-- is post decrement operator
Why 0 because --b is pre decrement operator
so 1 && 0 returns 0 and this value is stored in d
So the output: a = 0, b = 0, c = 1, d = 0
You're mixing up a-- with --a. The result of the expression a-- is a before the decrement, while --a is a after the decrement; in other words:
int a = 1;
int b = a--; // b == a == 1
int c = --b; // c == b-1 == 0
As a result, you have:
int d = a-- && --b;
// => 1 && b-1
// => 1 && 0
// => 0

Why c is not incremented in the output?

I was working on the Basics of C and was trying to solve the problem below could any one explain why the output of variable c is different?
What is the output of the following program?
int main()
{
int a = -3, b = 2, c= 0, d;
d = ++a && ++b || ++c;
printf ("a = %d, b = %d, c = %d, d = %d", a, b, c, d);
}
Ans: -2, 3, 0, 1
Why c is not incremented in the output ?
The variable c is not incremented because the RHS (right-hand side) of an || is not executed unless the LHS evaluates to false, and the LHS evaluates to true. The C || and && operators are 'short-circuit' operators; they do not evaluate the second operand unless the first is insufficient to determine the overall truth of the expression.
The && binds tighter than the ||, so the operation can be parenthesized as:
d = (++a && ++b) || ++c;
The value of ++a is -2, which evaluates to true (because any value that is not 0 evaluates to true); the value of ++b is 3, which evaluates to true; so the value of the && term is true. Because true || false and true || true both evaluate to true, there is no need to evaluate the RHS to know the overall result. (The analogous rule for && is that if the first term evaluates to false, there is no need to evaluate the second because the overall expression must be false. If you had a = -1; before the test, then b would not be incremented, because ++a would be zero or false, so the RHS of the && is unevaluated. Of course, then c would be incremented because the LHS of the || would be false, and the RHS would have to be evaluated to determine the overall result.)
Because ++a && ++b evaluates to true.
It's called short-circuiting. Expressions inside conditions are evaluated from left-to-right. If your case, if the first condition in the OR clause is evaluated to true, there's no point for the second one to also be evaluated, since the whole expression is known to be true already.
In C, the boolean logic operators && and || are short-circuiting. This means that they only evaluate their right side, if evaluating the left side is not enough to know the answer.
For your code, this has the effect of never evaluating ++c, since the left-hand side is not zero and thus the boolean or's result will be true, and there's no need to do more work.
It is lazy boolean expressions evaluation.
The execution is:
++a gives -2
++b gives 3
-2 && 3 gives 1
Okay! No need to check result of ||. So ++c is not evaluated.
The rule is: expression part X is not evaluated in cases: (0 && X), (1 || X). Here 1 is "not 0" of course.
d= ++a && ++b || ++c
d= ++(-2) && ++b || ++c
d= -1 && ++b || ++c
d= true && ++b || ++c
d= true && ++2 || ++c
d= true && true || ++c
d= true || ++c
d= 1
That's roughly how it works behind the scene...

Does C always evalute all statements connected with && or ||

pretty simple question I have here, but I couldn't find the answer:
Assume I have some conditional clause made up of several conditions. E.g. something like
if((a == b && strcmp(string1, string)) || x <= 5)
My question is: Will all of those statements be evaluated, no matter what the result of the first ones was, or will the evaluation stop once the result is clear.
As I am not sure whether my question is clear, here's an example:
if(a == 5 || b > 12 || (c = someFun()) == 3)
In this case, if a == 5, no further checks would be required, because the result of the big statement is TRUE, so we could simply continue. This would mean that someFun() would not be evaluated.
Is this the case? I know Java makes a difference here between && and & resp. || and | (the latter aren't available in C anyways), but I do not know how C handles this
These operators are short-circuiting in C (and C++).
C evaluates until it knows the answer, so:
EvalsToTrue() && EvalsToAnything() evaluates both
EvalsToFalse() && EvalsToAnything() evaluates only the first
EvalsToTrue() || EvalsToAnything() evaluates only the first
EvalsToFalse() || EvalsToAnything() evaluates both
The left-hand side expression is always evaluated. The right-hand side expression is evaluated as follows:
a || b -- b will be evaluated only if a evaluates to false
a && b -- b will be evaluated only if a evaluates to true
&& has higher precedence than ||, thus
a || b && c -- b && c will be evaluated only if a evaluates to false
a && b || c -- c will be evaluated only if a && b evaluates to false
(a || b) && c -- c will be evaluated only if a || b evaluates to true
a && (b || c) -- b || c will be evaluated only if a evaluates to true
a && b && c -- c will be evaluated only if a && b evaluate to true
a || b || c -- c will be evaluated only if a || b evaluate to false
Evaluation starts at left most.. and exits when the overall condition is no longer valid..

Resources