Why The Value Of K is Not Increasing in this code? - c

#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;
}
The value of k increases if i am using a || operator but in case of && the value is not increasing what would be the reason for that , i am very confused.
The out put is -2,3,0,1

You have a test in your code:
m = ++i && ++j || ++k;
When you use multiple tests like this, you will first evaluate ++i && ++j. If it's true, you will never evaluate the || ++k part (because m would be true anyway). This is called lazy evaluation.
If ++i && ++j had been false in your example, k would have been increased because the last part of the test would have been evaluated.

if the operators of “&&”are not zero,it will come true,then the rest part will not be used.
In c,if it is not zero,it is true.

It is called lazy evaluation. false && b is always false whatever b might be.
In your case:
m = ++i && ++j || ++k; evaluates to m = true || ++k; which leads to ++k not being evaluated because of lazyness.

Because ++k is not evaluated as ++i && ++j evaluates to true.

The OR condition is lazily evaluated.
The ++k is never executed, because the first part of the condition is not true.

expressions after || when the values before it evaluate to true will NOT be evaluated.
(c=10)|| (y=20)
In this example, c=10 evaluates to true, due to which y=20 will not be evaluated.

Related

C Program Output Complexity

Could you please explain why the following program is giving such outputs?
#include<stdio.h>
int main()
{
int i=-3,j=1,k=0;
int m;
m=++i || ++j && ++k;
printf("i= %d\nj=%d\nk=%d\nm=%d", i,j,k,m);
return 0;
}
Output:
i= -2
j=1
k=0
m=1
Since ++i is essentially true, because it is not 0, therefore the || other part will not be evaluated, since it does not matter at this point, the expression is true. Therefore j and k will not change. true is 1, that is why m is 1.

Why doesn't ++i || ++j && ++k give the expected value

I want to know why the value of k is 1 in the below code.
I think ++i || ++j && ++k is executed along the order:
((++i || ++j) && ++k)
So, in the first fragment, (++i || ++j), ++i is true, so ++j is not evaluated, so i=2, j=1.
Next, in the second fragment, (true && ++k), so ++k is evaluated, and then k=2.
#include <stdio.h>
int main(void)
{
int i, j, k;
i = 1; j = 1; k = 1;
printf("%d ", ++i || ++j && ++k);
printf("%d %d %d\n", i, j, k);
return 0;
}
But,
printf("%d %d %d\n", i, j, k);
shows
2 1 1
I don't know what was mistaken or what I've misunderstood.
The logical AND operator && has higher precedence than the logical OR operator ||. So the expression is actually parsed as:
++i || (++j && ++k)
++i evaluates to true so the entire right side of the ||, i.e. ++j && ++k, is not evaluated. This results in neither j nor k being incremented.
It can be difficult to remember all the precedence rules, both for yourself and for others who read your code. So when in doubt, use parenthesis to clarify your intentions.
Running with compiler warnings, or a good editor like Atom.io, reveals the problem.
cc -Wall -Wshadow -Wwrite-strings -Wextra -Wconversion -std=c99 -pedantic -g `pkg-config --cflags glib-2.0` -c -o test.o test.c
test.c:8:30: warning: '&&' within '||' [-Wlogical-op-parentheses]
printf("%d ", ++i || ++j && ++k);
~~ ~~~~^~~~~~
test.c:8:30: note: place parentheses around the '&&' expression to silence this warning
printf("%d ", ++i || ++j && ++k);
^
( )
1 warning generated.
It's a precedence issue. Operators in an expression are not evaluated left-to-right but rather in precedence order. ++i || ++j && ++k is being evaluated as ++i || (++j && ++k) because && has a higher precedence than ||.
To avoid these issues, turn on compiler warnings and make it a habit to put parens around anything that might be ambiguous.

Effect of the ||-operator on ++x

#include<stdio.h>
int main()
{
int i=0, k=0, m;
m = ++i || ++k;
printf("%d, %d, %d\n", i, k, m);
return 0;
}
returns
1,0,1
Why is k = 0 and not 1? what is the effect of the ||-operator on the ++k?
Thanks!
example: https://ideone.com/Fjsbii
In || OR , if first condition is true, it will not check second condition.(it will skip 2nd condition).
As
m = ++i || ++k;
in this condition after ++i, value of i will become 1, as first condition is true, so it will skip second condition. so the operation ++k will not be performed.
And hence k will remain 0.
Same as if you are using && , and first condition is false it will skip second condition. and result will be 0 (false).

left-hand operand of comma expression has no effect

for (count = index, packet_no = 0;
count < TOTAL_OBJ, packet_no < TOTAL_PKT;
count++, packet_no++)
=> left-hand operand of comma expression has no effect.
I find the above code is correct and could not understand why this error comes.
This is how the comma operator works, what you want to do is to use OR or AND (probably AND in your case):
// the condition for resuming the loop is that one of the conditions is true
count < TOTAL_OBJ || packet_no < TOTAL_PKT
// the condition for resuming the loop is that both conditions are true
count < TOTAL_OBJ && packet_no < TOTAL_PKT
You have three comma operators in each of the three terms of the for statement. The warning is for term 2.
Both expressions of terms 1 and 3 are executed as expected.
The left operation of the term 2 is evaluated only as a void, doesn't take part in the for condition, and therefore leads to your warning.
The conditional statement(for, while or if ) having conditional expressions with comma operator(s), the value of last expression is the conditional value(True or False) of conditional statement.
For ex.
int i = 1;
int j = 0;
int k = 1;
if(i, j, k) {
printf("Inside");
}else {
printf("Outside");
}
prints "Outside" as comma operator is evaluated from left to right and k is the last expression evaluated in if statement which returns false.
int i, j;
if(i = 0 , j = 1) {
printf("Inside");
}else {
printf("Outside");
}
Above prints "Inside". j = 1 is the last expression evaluated inside the if statement which has true value.
int i = 1;
int j = 0;
int k = 1;
if(i, j, k) {
printf("Inside");
}else {
printf("Outside");
}
Correction to above: This code will print "Inside" as the comma operator is evaluated from left to right and k is the last expression evaluated in the if statement, which returns true since k = 1.

What will the following code evaluate?

I had the following code in a test.I am confused about what (i,j) evaluates,while reading about the "," operator i found that it just evaluates the variables or functions but what does it do here?
main()
{
int i = 10, j = 20;
j = i ? (i, j) ? i : j : j;
printf("%d %d", i, j);
}
(i,j) is exactly the same as just j, because i is just a variable and evaluating it doesn't cause any side effect.
So basically it's just obfuscation here.
in (i,j), the , operator does nothing because the left-hand side expression does not have side-effects.
The assignment is thus equivalent to:
j = i? (j? i : j) : j;
And since i and j are non-zero, to j = i;
The comma operator can be used to link the related expressions together. A comma-linked list of expressions is evaluated left-to-right and the value of the rightmost expression is the value of the combined expression. It acts as a sequence point.
A sequence point guarantees that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed.
So, any expression/assignment will be completed & only then will the next expression to the right be evaluated.
For example,
b=(a=4,a=5);
gives,
a=5
b=5
Also, note that the comma operator ranks last in the precedence list of operators in C.
It will print:
10 10
This is because you can break the expression down like:
j = i ? ((i, j) ? i : j) : j;
The comma operator evaluates to the last expression - so (i, j) == j. That is non-zero, so the center expression evaluates to i. 'i' being non-zero, the outer expression evaluates to i, so j is assigned to the value of i.
This is equivalent to:
int main() {
int i = 10, j = 20;
if (i != 0) {
(void)i; // Do nothing with i.
if (j != 0) {
j = i;
} else {
j = j; // Assign j to itself.
}
} else {
j = j; // Assign j to itself.
}
printf("%d %d", j);
}
Looks like typical software written test question. It is used to confuse candidates. As suggested by sepp2k above it is same as j. One more interview question
i = 10; j = 20;
1) k = i,j;
2) k = (i,j);
Answer for 1 will be 10 and answer for 2 will be 20. As coma operator doesnt do anything. I hope this will clear more.
It's not really doing anyting. It's evaluating the expression i, discards the result, evaluates the expression j and returns the result.
As evaluating the expression i has no side effects, (i,j) has the same meaning as just j.
main()
{
int i = 10, j = 20; // i=10, j=20
j = i ? /*if i */ ( (i, j) ? /* if j (1) */ i : /* else */ j ) : /* else */ j; // Added parenthesis and see (2)
printf("%d %d", i, j); // Will therefore print 10 10
}
it is equivallent to if(j) because (i,j) evaluate to j because i has no side effect.
all ifs evaluate to true because i and j are ints and are non zero

Resources