how the precedence and associativity works in the following example? [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
int i=3,j=1,k=0,m;
m=++i || ++j && ++k;
printf("%d%d%d%d",i,j,k,m);
//output is 4 1 0 1enter code here
//can anyone explain why k=0 and j=1 only

m = ++i || ++j && ++k; is grouped as m = ++i || (++j && ++k); since, && has higher precedence. But, they are evaluated from left to right.
Since, ++i = 4, which a non-zero number, the right hand expression is not evaluated. I mean (++j && ++k) is not evaluated since, left hand expression result is non-zero.
For A||B, if A = 1, then results is always 1, irrespective of the value of B.
Since, the right hand expression is not evaluated, the values of j and k remain same.
This feature is called "Short Circuit Evaluation".

Precedence and associativity only affect how operators are grouped with operands - they do not affect the order in which expressions are evaluated. Both || and && force left-to-right evaluation. Also, remember that the && and || operators short-circuit as follows:
In the expression a || b, b will only be evaluated if a evaluates to zero
In the expression a && b, b will only be evaluated if a evaluates to non-zero
The expression
++i || ++j && ++k
is parsed as
(++i) || ((++j) && (++k))
and is evaluated as follows:
++i is fully evaluated and all side effects applied;
The result of ++i is 4, which is non-zero;
The || does not evaluate the right operand if the left operand is non-zero, so ++j && ++k is not evaluated at all;
When everything is said and done, only i is updated, j and k are not.

Related

C: Is there any wrong understanding about short-circuit evaluation? [duplicate]

This question already has answers here:
Short circuit evaluation of a statement with ++ operator in C
(2 answers)
Closed 6 months ago.
The community reviewed whether to reopen this question 6 months ago and left it closed:
Original close reason(s) were not resolved
Hi I have little confused about logical operator.
According to KNK C chapter 5 exercise 3-4.
int i=1;
int j=1;
int k=1;
printf("%d\n",++i || ++j && ++k);
printf("%d %d %d",i,j,k);
I thought the result is 1\n 2 1 2 due to the short -circuit evaluation
like ((++i || ++j) && ++k ).
But the answer is 1\n 2 1 1.
Why does variable k increase?
From C Operator Precedence:
Precedence
Operator
Description
Associativity
11
&&
Logical AND
Left-to-right
12
||
Logical OR
Left-to-right
Since && has precedence 11 and || has 12, the expression ++i || ++j && ++k is equal to this:
++i || (++j && ++k)
Left-to-right associativity makes it evaluate ++i first, concludes that it's true and short-circuits so (++j && ++k) will not be evaluated.
The result is therefore
1
2 1 1

Explain the logic [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
#include <stdio.h>
//Compiler version gcc 6.3.0
int main(void)
{
int i=10, j=2, k=0, m;
m=++i || ++j && ++k;
printf("%d,%d,%d,%d",i,j,k,m);
}
can anyone explain the logic, Output is 11,2,0,1
Due to the priorities of operations this expression statement
m=++i || ++j && ++k;
is equivalent to
m = ++i || ( ++j && ++k );
You can imagine it like
m = expression1 || expression2;
where expression1 is ++i and expression2 is ( ++j && ++k )
According to the C Standard (6.5.14 Logical OR operator)
4 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.
As expression1 compares unequal to 0 (its value is equal to 11) then expression2 is not evaluated.
Thus only expression1 is evaluated and it is unequal to 0.
According to another quote from the same section of the C Standard
3 The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
The result of the evaluation of the right side is equal to 1 that is assigned to the variable m.
Thus only the variable i and m were changed. The variables j and k were not changed because the expression where they are present as operands was not evaluated.
i starts as 10, but is incremented to 11, before it is tested.
m is being assigned a boolean result, so will be either 0 or 1.
i is non zero so evaluates to true for a boolean expression, therefore, the expression after the || do not need to be evaluated, as || is a boolean short circuit evaluator.
Hence your output.

Understanding operators in C [duplicate]

This question already has answers here:
OR and AND operation in C
(2 answers)
Closed 7 years ago.
I am struck on a basic problem with operators. Here is the problem
int i=3, j=2, k=1, m;
m = ++i || ++j && ++k;
printf("%d %d %d %d", i, j, k, m);
As i worked on this and evaluated the ans as
4 3 2 1
But C is not happy with my ans and evaluates the above as
4 2 1 1
But i dont understand how. Why ++j is doesn't updates the value of j. And also ++k doesn't updates the value of k.
Anybody here please explain this how it worked.
m = ++i || ++j && ++k;
The && operator has higher precedence than ||, so this is equivalent to:
m = ++i || (++j && ++k);
Both && and || are short-circuit operators; if the left operand determines the result, the right operand is not evaluated. Since ++i (which yields 4) is "truthy", the right operand (++j && ++k) is not evaluated, and j and k are not incremented. So i becomes 4, and j and k retain their initial values of 2 and 1, respectively.
The result of the || operator is either 0 (for false) or 1 (for true); since the condition is true, the value 1 is assigned to m.
Result:
4 2 1 1
In C, || is a short-circuit operator. This means when evaluating the expression a || b, it will only evaluate b if a is false. If a is true, then the expression will always be true regardless of b.
Since ++i gives a truthy value, ++j && ++k will not be evaluated.

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 the given C code be interpretated by different Compiler [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I have a code below and wanted to know what could be output.What i would like to see how different compiler would interpret this particular piece of code.
int main()
{
int i = -1, j = 2, k = 0, m;
m = ++i || ++j && ++k;
printf("\n %d %d %d %d \n", i, j, k, m);
return 0;
}
Now the question is while handling this code would compiler go by the rule which says
This expresion can be seen as
m = ++i || (++j && ++k);
as && has higher precedence over || and the result would be 0 2 0 1
or
This expresion can be seen as
m = ++i || (++j && ++k);
but compiler still will try to short circuit. so it evaluates ++i, since it's 1,(++j&&++k) >are not evaluated.so ans is 0 3 1 1
The expression ++i || ++j && ++k will group like so due to precedence:
++i || (++j && ++k)
One of the few rules C has about evaluation order of expressions is that the left-hand side of the || and the `&& operators must execute before the right-hand side (for short circuiting). This is a non-optional language requirement.
That means that ++i has to be evaluated first. It will return 0 (it does not evaluate to 1 as you mistakenly mention in the question). Since that's not enough to short circuit the || operation, the right side will need to be evaluated. A similar process will occur for evaluation the && operator (and both sides of the && operation will need to be evaluated).
The resulting output will be:
0 3 1 1
regardless of the compiler. There is no undefined, unspecified, or implementation defined behavior evaluating that expression.
The expression ++i || ++j && ++k will group like so due to precedence:
++i || (++j && ++k)
One of the few rules C has about evaluation order of expressions is that the left-hand side of the || and the `&& operators must execute before the right-hand side (for short circuiting). This is a non-optional language requirement.
That means that ++i has to be evaluated first. It will return 0. Since that's not enough to short circuit the || operation, the right side will need to be evaluated. A similar process will occur for evaluation the && operator (and both sides of the && operation will need to be evaluated).
The resulting output will be:
0 3 1 1
regardless of the compiler. There is no undefined, unspecified, or implementation defined behavior evaluating that expression.
One way to get the output you mention in your question is to use the following expression instead:
m = --i || ++j && ++k;
In this case, --i evaluates to -2 and the short circuiting rule requires that the right side of the || operator not be evaluated. So j and k are left alone.

Resources