#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).
Related
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.
I've used Code::Blocks to find the result, and it gives me 2 at the end, where i + j = 1 + 1.
#include <stdio.h>
int main(void) {
int i = -1, j = 1;
for(i++; i++; i++)
j++;
printf("%d",i + j);
return 0;
}
How does i get to be 1, and why was j not incremented?
You start with i == -1, j == 1.
Then you run the first i++, which will make i == 0. The result (which is the original value of i) is unused.
Then you test for the first time in i++. Since i is already 0, the test is false, so the for loop will quit. Now the post-increment runs, which makes it i == 1, and the loop exits.
Note how j++; was never reached!
To see it more clearly, you can think about the for loop in the following equivalent way:
i++; // init statement
while (i++) { // condition
j++; // body of the for loop
i++; // iteration expression
}
Here's the order in which it executes:
i is -1 and j is 1
i is incremented (after which i == 0)
The loop checks if i != 0. Since i is 0 at this point, the contents of the loop are skipped.
i is incremented again (after which i == 1)
The code prints i + j, which is 2 because j is unchanged and i is 1.
Here's a program with a while loop that does the same thing as the program in your question:
int main(void) {
int i = -1, j = 1;
i++;
while(i++)
{
j++;
i++;
}
printf("%d",i + j);
return 0;
}
To directly answer your question:
i is 1 afterwards because it is incremented twice from an original value of -1.
j is not incremented because the contents of the loop are skipped.
Let me first explain how for loop execution happens:
The init step is executed first, and only once. This step allows you to declare and initialize any loop control variables. You are not required to put a statement here, as long as a semicolon appears.
Next, the condition is evaluated. If it is true, the body of the loop is executed. If it is false, the body of the loop does not execute and the flow of control jumps to the next statement just after the for loop.
Increment operator: value of i increments after execution if it is i++
Explanation of your code:
for(i++; i++; i++)
At init step i++ been executed but i will be still 0 until it get to condition step of for loop.
i becomes zero it means condition is false but at same time one more i++ already executed.
As condition is false for loop statement will never be executed and value of i will be 1 and value of j remains 1.
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.
#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.
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