Trouble with increment operator [duplicate] - c

This question already has answers here:
Short circuit evaluation and side effects [duplicate]
(3 answers)
Closed 6 years ago.
This is the exemplar code that I encountered in entry level Computer Programming course:
#include <stdio.h>
int main()
{
int l = 20, m = 10;
int z;
z= l++ || m++;
printf("z = %d l = %d m = %d\n", z, l, m);
}
The code prints l=21, m=10 and z=1
values of l and z are what was expected by me, but value of m is troubling me. Shouldn't it be 11 as m++ is present in code.

It is because m++ would only be executed if l++ == 0. Since l++ evaluates to 20 then m++ is never executed. If l was 0 initially then m++ would be executed.

z= l++ || m++;
In your expression, l first assign value and after incremented one.
In Logical or (||) operation, If the left operand is non-zero, then right operand is not evaluated and the result is true. That's why l become 21 and m not evaluated and it's value is 10.
C standard(N1256 : 6.5.14-paragraph 4) say's:
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.

What you see is called short circuit evaluation.
Your line here:
z= l++ || m++;
Says, Check the value of l (increment while checking it). If l is non-0, set z to 1. If l is 0, check the value of m (increment while checking it). if m is non-0, set z to 1. Otherwise set z to 0.
Essentially, when the first of the two checks (l++) already evaluates true, there is no need for the system to check the second condition, so it doesn't, and thus also fails to increment m.

Related

Not understanding the line of statement [duplicate]

This question already has answers here:
Logical Operators and increment operators [duplicate]
(1 answer)
Logical Operators in C
(8 answers)
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 4 years ago.
Here is the code
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;
}
And output:
-2, 2, 0, 1
But i don't understand the line m = ++i||++j&&++k; How it get's executed.
Someone please explain..Thanks!
Initially you have the 4 variables:
i = -3
j = 2
k = 0
m is uninitialized
m = ++i||++j&&++k; is executed left to right. so first one is ++i - I suggest reading about the differences between i++ and ++i - In this case i is increased by 1 and become i=-2
-2 is a true expression, therefore m becomes 1 and the rest of the expression is not evaluated. Because true or anything else is always true anyway.
So final outcome:
i = -2 (increased)
j = 2 (unchanged)
k = 0 (unchanged)
m is 1 (true)
Logical OR operation (expr1 || expr2) employs short-circuiting behavior. That is, expr2 is not evaluated if expr1 is logical 1 (true).
The expression with logical OR operator evaluate to true if any of the two operands is non-zero.
In this expression:
m = ++i||++j&&++k;
|_| |______|
LHS RHS
The i is initialized with -3. ++i will evaluate to -2.
-2 is a non zero value hence evaluate to logical true and the RHS part of the expression will not evaluated.
Since the whole expression evaluated to true, the value 1 is assigned to m.

execution of ternary operator

#include <stdio.h>
#define max(x,y)(x)>(y)?x:y
int main() {
int i = 10;
int j = 5;
int k = 0;
k == max(i++, ++j);
printf("%d%d%d ", i, j, k);
return 0;
}
I know the answer. It is 11 7 0 but how? please help me with the execution of the ternary operator.
The statement
k==max(i++,++j);
is expanded to
k==(i++)>(j++)?i++:j++;
Note that == has higher precedence than ?: operator and therefore the above expression is equivalent to
( k == ((i++)>(j++)) )?i++:j++;
Since (i++)>(j++) will be true, therefore k == ((i++)>(j++)) is evaluated as false and hence j++ (and it's value become 7) will be evaluated (i++ will be skipped).
NOTE: The above expression does not invoke undefined behavior because there exists sequence point between the evaluation of the first operand of the ternary operator and the second or third operand. For example, the expression
a = (*p++) ? (*p++) : 0
has well defined behavior.
This question is definitely a trick question that will catch many unsuspecting C programmers. The different responders here have more than 100 years of compounded experience in C, yet it took several tries to get this right:
The expression k == max(i++, ++j); expands to:
k == (i++)>(++j)?i++:++j;
Which is parsed as this (== has lower precedence than >, but higher precedence than ?):
(k == ((i++) > (++j)))
? i++
: ++j;
The ternary operator evaluates the test (i++)>(++j), which is true for the values in the program, hence evaluates to 1, different from the value of k, so it proceeds to evaluate the third expression j++, which increments j a second time and returns the intermediary value 6. There is a sequence point between the test and the branch that is executed, so it is OK to increment j twice. The second branch is not executed at all since the test evaluated to false.
i is incremented once, its value becomes 11.
j is incremented twice, its value is 7.
k is not modified by the above statement, because == is the comparison operator, not the assignment operator.
Hence the output is 11 7 0
Notes:
The program uses a macro max that evaluates its arguments more than once and they are not properly parenthesized in the expansion: 2 errors that illustrate the shortcomings of macros. This macro should be names MAX to emphasize the fact that its arguments should not have side effects and its expansion should be fully parenthesized this way:
#define MAX(x,y) ((x) > (y) ? (x) : (y))
A better alternative is to make it an inline function:
static inline int max(int x, int y) {
return x > y ? x : y;
}
If the program had this statement:
k = max(i++, ++j);
The output would be 12 6 11 because unlike ==, = has lower precedence than ? so the statement would expand to:
k = ((i++) > (++j))
? i++
: ++j;
You can study the table of operator precedence for C. There are in my humble opinion too many levels and it is very difficult to memorize all of them, especially since some of them are rather counter-intuitive: print a copy and keep it handy or make a bookmark. When in doubt, use parentheses.
You're using a double equal sign, which is a comparison. k==max(i++,++j); compares the return value of max to k, which is 0.
Instead, try changing the == to =.

Increment and logical operators precedence [duplicate]

This question already has answers here:
Short circuit behavior of logical expressions in C in this example
(1 answer)
Operator Precedence vs Order of Evaluation
(6 answers)
Closed 7 years ago.
In the program shown below, prefix should be evaluated first because it has higher precedence, But answer is -2, 2, 0, 1 and it is explained in book "as LHS of || is true RHS is not evaluated."
Why is it so? All the increments should performed first and then logical should be checked because of precedence.
#include<stdio.h>
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;
}
Don't get confused with Precedence and Order of evaluation.
The order of evaluation of logical OR || is left to right.
So if left = true then left || right will never execute right. In your code exactly same happened.
As you know, any non zero value treated as true in C, hence, ++i or -2 is true. So,
m = ++i || ++j && ++k;
m = true || bla bla bla; //right not even checked!
m = true
m = 1
And you get the output as expected.
The logical && and || operators fully evaluate the LHS before doing any evaluation of the RHS.
In the code shown, since ++i is -2, the LHS of the || evaluates to true (1) and the RHS is not evaluated. Therefore, neither j nor k is incremented. The printed result follows: m was assigned 1, i became -2, and j stayed as 2 and k stayed as 0.
The only remaining issue is that && binds tighter than ||, so:
a || b && c
is equivalent to:
a || (b && c)
so if a evaluates to true (non-zero), then neither b nor c is evaluated.
Operator precedence is a completely different thing. Order of evaluation is determined by side effects and sequence points.
see this manual on order of evaluation.

Confusion with post increment and logical operator?

#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)

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