C loop with two conditions - difference [duplicate] - c

This question already has answers here:
C comma operator
(4 answers)
Closed 5 years ago.
Whats the difference between:
int i;
for( i=0;i<5 && i<3;i++)
{
printf("stackoverflow.com");
}
and
int i;
for( i=0;i<5 , i<3;i++)
{
printf("stackoverflow.com");
}
I mean use of && instead of ','
Regards

In the second code block, only i < 3 is actually used to evaluate whether the loop should exit. The i < 5 expression is evaluated, but its value is discarded. See the comma operator for more info.
There is functionally no difference between your examples because i < 3 is the limiting expression and appears second. Both loops will exit when i reaches 3. However, if you switched the terms so that you have i < 3, i < 5, then the second kicks out when it reaches 5 because only the value of i < 5 is considered.

In this case they will do exactly the same.
The thing that differs is that in the first case i<3 will not be evaluated every time. A statement on the form A && B will only execute B if the return value of A is true. The reason is that the logical value of && is true if both operands are true. If one of them are false, the whole expression is false, so if the left operand evaluates to false, there's no need to evaluate the right operand.
The comma operator on the other hand evaluates both operands, but the result of the left operand is discarded.

When using the comma operator , in a statement like the:
( <expression1>, <expression2> )
the <expression1> is evaluated and discarded, then the <expression2> is evaluated and its value is returned. In summary the right most expression is evaluated and its value returned. Other expressions are evaluated and discarded. So your statement of:
for(i=0; i<5 , i<3; i++)
is equivalent to:
for(i=0; i<3; i++)
As for the first statement, this expression:
(i<5 && i<3)
is a simple AND boolean evaluation. A funny one because it is enough to say:
(i<3)
Long story short, who ever made this example probably expects you to say "both conditions evaluate to second expression".

Related

Difference between i++ and ++i

So, I understand that i++ increments post the condition is fulfilled, while ++i increments before the condition is fulfilled. That takes me to my question:
#include<stdio.h>
int main()
{
int i=0;
while(++i<10)
printf("%d\n",i);
return 0;
}
Now here we need the initialization of i from 0 as when it goes in the while loop, it will get incremented first, and thus it will be like while(1<10), and so it will print numbers from one to ten.
Second code:
#include<stdio.h>
int main()
{
int i=0;
while(i++<10)
printf("%d\n",i);
return 0;
}
Now since i++ increments after the value has been used, so why do we initialize i from i=0, as if it gets incremented after the comparision of value of i takes place, then why isn't 0 getting printed as well because the first loop should go like while(0<10), and not like while(1<10)? So, why is zero not getting printed?
Thank you for your time.
Yes, the first condition will evaluate to 0 < 10. You can verify that by changing it to while (i++ < 1) and see that the loop still runs (once), so clearly it's using 0 for the condition (1 < 1 would be false of course).
So why does it print 1? Because it doesn't print whichever value was used for the condition. It prints the current value of i. And the current value of i is 1 at that point because i was incremented right after it was used in the condition.
The difference of pre- and post- increment applies only to the value that the expression evaluates to.
After the evaluation of i++<10 is completed, the incrementation is also completed, and i has the value 1 in the first iteration.
printf("%d\n",i); is executed after the evaluation of i++<10, so i has the value 1 here in the first iteration.
Zero isn't printed because i is incremented right after the comparison, like this:
while(i<10) {
i += 1;
printf("%d\n",i);
}
The first sentence of your question is almost the answer:
i++ increments post the condition is fulfilled
It's incremented after the condition is checked, so i++ < 10 will increment i regardless of whether the condition ends up true or false.
The operation of ++ is not done before or after any “condition” it is in. It must be completed sometime in or around the full expression it is in. The answers that say i is updated “before” or “after” the ++i or i++ is evaluated are incorrect.
Prefix ++i does two separate things that may happen in any order:
It evaluates to the value of i after one is added.
It adds one to the stored value of i.
Postfix i++ does two separate things that may happen in any order:
It evaluates to the value of i before one is added.
It adds one to the stored value of i.
That change to the stored value of i is called a side effect. It is disconnected from the main evaluation of the expression. It can be performed before, during, or after the evaluation of i, but the evaluation still returns the pre- or post-increment value, as described above.
A full expression is one that is not contained inside another expression. So, in while (++i < 10), ++i < 10 is a full expression. The side effect can occur before any part of that is evaluated, after the value of i plus one is calculated, or after the < is evaluated. It can also occur in parts (such as updating the bytes of i one by one) during the evaluations. However, the side effect must occur after any previous full expression and before any later full expression. That is because the C standard says there is a sequence point between any two full expressions. (And there are some other rules about order of execution.)
Even if the stored value of i is updated before i++ or after ++i, the expression must still produce the value of i before or after the increment, respectively. For example, for i++, the compiler can fetch i, add one, store i, but then use the pre-add value in the expression.
The result of i++ is the value of i. As a side effect i is incremented.
The result of ++i is the value of i + 1. As a side effect i is incremented.
The statement
x = i++;
is logically equivalent to
tmp = i;
x = tmp;
i = i + 1;
with the caveat that the assignments to x and i can happen in any order, or even simultaneously (interleaved or in parallel).
Similarly, the statement
x = ++i;
is logically equivalent to
tmp = i + 1;
x = tmp;
i = i + 1;
with the same caveat as above. Again, these are logical equivalents, not what the compiler actually generates - depending on the compiler and the code involved there may not be a temporary.
In the second code, the increment will take place after the condition but before the printing statement.
Thus, the incremented value of i is printed.
This is your answer in simple language.

Why does this loop run infinite times? Comma separated conditions in for loop [duplicate]

This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 3 years ago.
Program code :
int main()
{
int i;
for (i = 0; i < 0, 5; i++)
printf("%d ", i);
return 0;
}
The loop above is executed infinite times.
What does i<0,5 mean, and how it is evaluated?
Based on operator precedence, this is interpreted as (i < 0), 5. The comma operator evaluates all statements, but discards their values except the last. So for practical purposes the loop reads as
for (int i = 0; 5; ++i) {...}
Because a non-zero value is interpreted as true in C/C++, this is equivalent to:
for (int i = 0; true; ++i) {...}
which is an infinite loop.
why i<0,5 how it is evaluated?
Because the value of a comma expression is its last value. The values in this comma expression arei < 0 and 5. This first is evaluated to false and thrown away! The second (and last) is 5 which is true. That is used as the for loop condition expression.
A for loop runs until its condition expression is false, so this loop run forever.
In the condition of the loop there is used the comma operator
for (i = 0; i < 0, 5; i++)
printf("%d ", i);
From the C Standard (6.5.17 Comma operator)
2 The left operand of a comma operator is evaluated as a void
expression; there is a sequence point between its evaluation and that
of the right operand. Then the right operand is evaluated; the result
has its type and value
So this expression with the comma operator
i < 0, 5
has two operands and can be rewritten for clarity like
( i < 0 ), ( 5 )
So the value of the expression according to the quote from the C Standard is the value of the second operand that is 5.
As 5 is not equal to 0 then the condition always evaluates to logical true and you have an infinite loop.
From the C Standard (6.8.5 Iteration statements)
4 An iteration statement causes a statement called the loop body to
be executed repeatedly until the controlling expression compares equal
to 0. The repetition occurs regardless of whether the loop body is
entered from the iteration statement or by a jump.155
It is very easy to check yourself. Try:
int main()
{
int i, y;
for (i = 0; i < 0, 5; i++)
{
y = (i < 0, 5);
printf("%d ", y);
}
return 0;
}
And you know that second expression in your list is the value of the comma expression.

What is happening in the if condition? [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 3 years ago.
One of my friends ask me about this code and I and he are unable to find out, what is happening in the if condition. Can you guys explain how this condition works?
int main()
{
int i;
if (i = (1, 2, 0))
printf("Mehrose");
else
printf("Hello ");
printf("%d\n", i);
return 0;
}
The output for this code is Hello 0
First, formatting as the compiler sees the code we get:
int main(void)
{
int i;
if(i=(1,2,0))
printf("Mehrose");
else
printf("Hello");
printf("%d\n",i);
return 0;
}
The if statement can be broken down:
Comma operator , is evaluated first, left-hand side of the operator is discarded. This repeats for each operator:
if(i=(1,2,0))
if(i=(2,0))
if(i=0)
The assignment operator = assigns a value of 0 to i, and returns the right-hand side of the expression:
if(0)
Recall that 0 is evaluated as false (is "falsy") and 1 is evaluated as true (is "truthy"). Thus the first condition fails and the second block is executed. "Hello" is printed to the standard output stream, followed by "0".
In the expression,
i=(1,2,0)
you're using the comma operator, which evaluates all its operands and yields the result of its rightmost operand - which is 0 here.
So 0 is assigned to i.
So it's equivalent to if (i = 0), which assigns 0 to i and yields the value of i which is false and thus it prints the string in the else branch.

Multiple conditions in a C 'for' loop

I came across this piece of code. I generally use '&&' or '||' to separate multiple conditions in a for loop, but this code uses commas to do that.
Surprisingly, if I change the order of the conditions the output varies.
#include<stdio.h>
int main() {
int i, j=2;
for(i=0; j>=0,i<=5; i++)
{
printf("%d ", i+j);
j--;
}
return 0;
}
Output = 2 2 2 2 2 2
#include<stdio.h>
int main(){
int i, j=2;
for(i=0; i<=5,j>=0; i++)
{
printf("%d ", i+j);
j--;
}
return 0;
}
Output = 2 2 2
Can somebody explain the reason? It seems to be checking only the last comma-separated condition.
The comma operator evaluates all its operands and yields the value of the last one. So basically whichever condition you write first, it will be disregarded, and the second one will be significant only.
for (i = 0; j >= 0, i <= 5; i++)
is thus equivalent with
for (i = 0; i <= 5; i++)
which may or may not be what the author of the code intended, depending on his intents - I hope this is not production code, because if the programmer having written this wanted to express an AND relation between the conditions, then this is incorrect and the && operator should have been used instead.
Of course it is right what you say at the beginning, and C logical operator && and || are what you usually use to "connect" conditions (expressions that can be evaluated as true or false); the comma operator is not a logical operator and its use in that example makes no sense, as explained by other users. You can use it e.g. to "concatenate" statements in the for itself: you can initialize and update j altogether with i; or use the comma operator in other ways
#include <stdio.h>
int main(void) // as std wants
{
int i, j;
// init both i and j; condition, we suppose && is the "original"
// intention; update i and j
for(i=0, j=2; j>=0 && i<=5; i++, j--)
{
printf("%d ", i+j);
}
return 0;
}
The comma expression takes on the value of the last (eg. right-most) expression.
So in your first loop, the only controlling expression is i<=5; and j>=0 is ignored.
In the second loop, j>=0 controls the loop, and i<=5 is ignored.
As for a reason... there is no reason. This code is just wrong. The first part of the comma-expressions does nothing except confuse programmers. If a serious programmer wrote this, they should be ashamed of themselves and have their keyboard revoked.
Do not use this code; whoever wrote it clearly has a fundamental misunderstanding of the language and is not trustworthy. The expression:
j >= 0, i <= 5
evaluates "j >= 0", then throws it away and does nothing with it. Then it evaluates "i <= 5" and uses that, and only that, as the condition for ending the loop. The comma operator can be used meaningfully in a loop condition when the left operand has side effects; you'll often see things like:
for (i = 0, j = 0; i < 10; ++i, ++j) . . .
in which the comma is used to sneak in extra initialization and increment statements. But the code shown is not doing that, or anything else meaningful.
Wikipedia tells what comma operator does:
"In the C and C++ programming languages, the comma operator (represented by the token ,) is a binary operator that evaluates its first operand and discards the result, and then evaluates the second operand and returns this value (and type)."
There is an operator in C called the comma operator. It executes each expression in order and returns the value of the last statement. It's also a sequence point, meaning each expression is guaranteed to execute in completely and in order before the next expression in the series executes, similar to && or ||.
Completing Mr. Crocker's answer, be careful about ++ or -- operators or I don't know maybe other operators.
They can affect the loop. for example I saw a code similar to this one in a course:
for(int i=0; i++*i<-1, i<3; printf(" %d", i));
The result would be $ 1 2$. So the first statement has affected the loop while the outcome of the following is lots of zeros.
for(int i=0; i<3; printf(" %d", i));

Comma operator in condition of loop in C

#include <stdio.h>
main()
{
int i;
for(i=0; i<0, 5; i++)
printf("%d\n", i);
}
I am unable to understand the i<0, 5 part in the condition of the for loop.
Even if I make it i>0, 5, there's no change in output.
How does this work?
On topic
The comma operator will always yield the last value in the comma separated list.
Basically it's a binary operator that evaluates the left hand value but discards it, then evaluates the right hand value and returns it.
If you chain multiple of these they will eventually yield the last value in the chain.
As per anatolyg's comment, this is useful if you want to evaluate the left hand value before the right hand value (if the left hand evaluation has a desirable side effect).
For example i < (x++, x/2) would be a sane way to use that operator because you're affecting the right hand value with the repercussions of the left hand value evaluation.
http://en.wikipedia.org/wiki/Comma_operator
Sidenote: did you ever hear of this curious operator?
int x = 100;
while(x --> 0) {
// do stuff with x
}
It's just another way of writing x-- > 0.
Comma operator evaluates i<0 Or i>0 and ignores. Hence, it's always the 5 that's present in the condition.
So it's equivalent to:
for(i=0;5;i++)
The coma operator is done to the initialization and to the increment part, to do something like for(i=0,j=20;i<j;i++,j--), if you do it in the comparation part it will evaluate the last one (as it was already answered before)
i<0,5 will always evaluate to 5, as always the right expression will be returned for ex1,ex2 .
The comma operator is intended for cases where the first operand has some side effects. It's just an idiom, meant to make your code more readable. It has no effect on the evaluation of the conditional.
For example,
for (i = 0; i<(i++, 5); i++) {
// something
}
will increment i, and then check if i<5.

Resources