how does this while loop in c programming works? [duplicate] - c

Studying for a computer science final.
I really cannot figure this question out.
What will be the output of this C program?
#include<stdio.h>
int main()
{
int i = 0;
while(i < 4, 5)
{
printf("Loop ");
i++;
}
return 0;
}
A. Infinite Loop
B. Loop Loop Loop Loop Loop
C. Loop Loop Loop Loop
D. Prints Nothing
Upon execution it prints loop for infinite times. Why is that happening? Why is there a comma inside the arguments of While loop? What does it do?

It will loop forever, because the condition of the while loop i < 4, 5 evaluates to 5, which is different than 0, therefore is considered true in C.
To learn more about that, read about the comma operator: https://en.wikipedia.org/wiki/Comma_operator
Briefly, when the comma operator is used, all of its operands are evaluated but the whole expression takes the value of the last one. For example:
int val = (1, 2, 3);
printf("%d\n", val);
Will print 3.

What you have in the while loop's condition is the comma operator, which evaluates its operands and yields the value of its right most operand.
In your case, it evaluates i < 4 condition and discards it and then evaluates the condition to just 5. So it's essentially equivalent to:
while(5)
{
printf("Loop ");
i++;
}
Which obviously results in infinite loop as the condition is always true. (remember that any non-zero value is always "true" in C). There's also a possible integer overflow due to i getting incremented in the infinite loop.

Related

Could you please explain why the value of i variable is 3 here after getting executed?

The semicolon has been added after the first while loop, but why is the value of the i variable 3 here, where j is 2?
#include<stdio.h>
int main()
{
int i=1;
while(i++<=1);
printf("%d",i);
int j=1;
while(j++<=1)
printf("%d",j);
return 0;
}
Both while loops run once (and once only); the difference is that, in the second case (the j loop) you are printing the 'control variable' inside the loop but, for the first case, you are printing it after the loop condition has evaluated to false. Also note that, in the first case, the semicolon immediately following the while statement defines the body of that loop as empty1.
Let's break down the first loop into steps:
On the first test of the condition, i++ evaluates to 1 and then i is incremented – so the loop runs.
On the second test, i++ evaluates to 2 (so the loop doesn't run) but i is still (post-)incremented, leaving it with the value of 3 (as shown in the output).
The same thing happens with j in the second loop but, in that case, as previously mentioned, you are displaying the value in the body of the loop (on its only run), so you see the value after the first (post-)increment.
As noted in the comments, if you add another printf("%d", j); after the body of the loop (which, in that case, consists of a single statement), you will see that j, too, has the value 3 when that loop has finished.
1 More precisely, the semicolon (on its own) defines a null statement, which forms the body of the while loop.
It is often helpful to clarify such 'null loops' by putting the semicolon on a line by itself (some compilers, with full warnings or static analysis enabled, may even suggest you do this):
#include<stdio.h>
int main()
{
int i = 1;
while (i++ <= 1)
; // Body of loop - Null Statement
printf("%d", i); // Loop has finished
int j = 1;
while (j++ <= 1)
printf("%d", j); // Body of loop
// Loop has finished
return 0;
}
For starters let;s consider how the postfix increment operator works. From the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the
operand. As a side effect, the value of the operand object is
incremented (that is, the value 1 of the appropriate type is added to
it).
Now consider this while loop
int i=1;
while(i++<=1);
In the first iteration of the loop the value of the expression i++ as the value of its operand that is 1. So the loop will iterate a second time, Due to applying the side effect to the variable i it will be equal already to 2 when the expression i++<=1 will evaluate the second time.
Now the value of i is equal to 2 and is greater than 1. so the loop will be interrupted. Again due to applying the side effect of the postfix increment operator to the variable i it will be equal to 3. This value is outputted in the following call of printf.
In simplest terms,
consider three things for each iteration of first while loop:
first iteration:
int i = 1;//initialization
while(i++<=1); //1. i evaluated as 1,
//2. loop condition is true causing loop to iterate again.
//3. ...but not before ++ causes i==2.
second iteration:
while(i++<=1); //1. i evaluated as 2,
//2. loop condition is false causing loop to eventually exit
//3. ...but not before ++ causes i==3.
printf is not included in the while loop (because of the semicolon) but
when program flow finally reaches printf("%d",i); the value of i is output as 3
In the second loop, because printf is included in the while construct, it will output the value of j for each iteration. For the same reasons as in loop one, it will also iterate only twice, and its values at time of output will be 2 & 3.
Using a debugger to set break points, and a watch on i, you can step through code such as this to see the sequence of these effects as they happen.
For explanation porpouses look at this example:
int main()
{
int i=1;
while(i++<=1)
printf("%d",i);
printf("%d",i);
}
The Output is:
2
3
Ok let's dive into the programm procedure:
Declaring i (i = 1)
while checking Condition and it's true because i++ returns 1(old Value). That's because the ++ are after the i. If you would code it like this ++i than it returns 2(new Value) (i = 2)
execute printf (i = 2)
while checking Condition and it's false because i++ returns 2 and 2 is not <= 1 (i = 3)
execute printf (i = 3)
Do you understand?
If it solved your thoughts jumble ;) mark it as answer.
You've got many answers already so I won't try to explain it in words but with an illustration in code. I've added two functions:
One that acts like a prefix increment operator (++i)
One that acts like a postfix increment operator (i++)
I'm only using the postfix version in the program though. I've added logging to the function so you can see how it works.
#include <stdio.h>
// this acts as if you put ++ before the variable
int preinc(int* p) {
++*p;
return *p;
}
// this acts as if you put ++ after the variable
int postinc(int* p) {
int rv = *p;
++*p;
printf("returning %d but incremented to %d\n", rv, *p);
return rv;
}
int main() {
int i=1;
while(postinc(&i) <= 1);
printf("end result: %d\n---\n", i);
int j=1;
while(postinc(&j) <= 1)
printf("in loop: %d\n", j);
printf("end result: %d\n", j);
}
Output:
returning 1 but incremented to 2
returning 2 but incremented to 3
end result: 3
---
returning 1 but incremented to 2
in loop: 2
returning 2 but incremented to 3
end result: 3
If you add the semicolon in the end of the while you will take: i = 3 and j = 3(IN THE OUTPUT).
If you add the semicolon only in the end of the printf and not to the while you will take i = 2 and j = 2(IN THE OUTPUT), but in the end you will, also, have the values
i = 3 and j = 3.
This happens because the "i" variable is incremented only after the first iteration of the loop, in which the empty statement (terminated by the semicolon) is evaluated.
that is why it is highly recommended to do "++i" rather than "i++", because then the incrementation is performed prior to the evaluation.
if you flip it here, you will see that i will be equal to 2 as well, regardless of the presence of the semicolon

Comma inside arguments of While Loop

Studying for a computer science final.
I really cannot figure this question out.
What will be the output of this C program?
#include<stdio.h>
int main()
{
int i = 0;
while(i < 4, 5)
{
printf("Loop ");
i++;
}
return 0;
}
A. Infinite Loop
B. Loop Loop Loop Loop Loop
C. Loop Loop Loop Loop
D. Prints Nothing
Upon execution it prints loop for infinite times. Why is that happening? Why is there a comma inside the arguments of While loop? What does it do?
It will loop forever, because the condition of the while loop i < 4, 5 evaluates to 5, which is different than 0, therefore is considered true in C.
To learn more about that, read about the comma operator: https://en.wikipedia.org/wiki/Comma_operator
Briefly, when the comma operator is used, all of its operands are evaluated but the whole expression takes the value of the last one. For example:
int val = (1, 2, 3);
printf("%d\n", val);
Will print 3.
What you have in the while loop's condition is the comma operator, which evaluates its operands and yields the value of its right most operand.
In your case, it evaluates i < 4 condition and discards it and then evaluates the condition to just 5. So it's essentially equivalent to:
while(5)
{
printf("Loop ");
i++;
}
Which obviously results in infinite loop as the condition is always true. (remember that any non-zero value is always "true" in C). There's also a possible integer overflow due to i getting incremented in the infinite loop.

Understanding the basics of the for loop in C language

can anyone explain the working of the for loop in the following code:
#include<stdio.h>
#include<conio.h>
int main()
{
char i=0;
for(i<=5&&i>=-1;++i;i>0)
printf("%d\n",i);
getch();
}
Let's break the for statement down, we have three phases, the initialiser, the test, and the modifier:
for(<Initialiser>; <Test>; <Modifier>)
<content>;
In your case:
for(i<=5&&i>=-1;++i;i>0)
// initialiser: i<=5&&i>=-1;
// test: ++i;
// modifier: i>0
The initialiser is done first. Here no assignment is done. Two boolean expressions (denoted by the >= and <= operators are compared in a logical &&. The whole initialiser returns a boolean value but it doesn't do anything. It could be left as a blank ; and there would be no change.
The test uses the pre-increment operator and so returns the result of i+1. If this result is ever 0 it evaluates as false and the loop will terminate. For any non-zero value it evaluates to true and continues. This is often used when i is initialised to a value less than zero and so the test will increment i until i+1 results in a zero, at which point the loop terminates.
Finally we have the modifier, which in this case simply uses the > operator to evaluate to a boolean value. No assignment is done here either.
The fact is that you've gotten the test and the modifier confused and put them in the wrong positions but before we sort that out let's see how it would work…
We begin with:
char i = 0;
…and for all intents and purposes this does the same thing as our for loops initialiser would do in normal circumstances. The next thing to be evaluated is the for loop's initialiser:
i<=5 && i>=-1;
Because i is 0 it is less-than-or-equal-to 5 and it is greater-than-or-equal-to -1. This expression evaluates to 1 but nothing is done with that value. All we've done is waste a bit of time with an evaluation.
Next up is the modifier to test whether or not the for loop's inner block should be executed:
++i;
This evaluates to 1 and also assigns that value to i. Now, as it's evaluated to a non-zero number, the loop executes:
printf("%d\n",i);
And the digit 1 is printed to the screen... Now it's the modifier that gets executed:
i>0
Well, i is 1 so that is greater-than 0. This evaluates to 1 (or true). Either way, this is ignored. The purpose of the modifier isn't to test or check anything. It's there so that you can change the state of the program each time the for loop iterates. Either way, the loop repeats and it will do this for a very long time. Why? Because ++i is going to evaluate to a non-zero number for a while. Whether or not it will ever terminate depends on how your system deals with integer overflows.
This is what you meant to do:
#include<stdio.h>
#include<conio.h>
int main()
{
for(char i=0; i<=5&&i>=-1; ++i)
printf("%d\n",i);
}
Do you see the difference? Our initialiser now starts the loop with the state of i as zero. We then test if it's within the bounds of -1 to 5 and each time we iterate we increment i by 1. This loop will output:
0
1
2
3
4
5
This snippet:
for(i<=5&&i>=-1;++i;i>0)
printf("%d\n",i);
Does the same as this:
i<=5 && i>=-1; //statement with no effect
while(++i)
{
printf("%d\n",i);
i>0; //statement with no effect
}
So, it's going to print i until ++i evaluates to 0. This will happen after i overflows and becomes negative, then incrementing towards 0. That will take 255 iterations to happen, since chars can store up to 256 different values.
for ( variable initialization; condition; variable update ) {
}
the variable initialization phase is done only once when the for loop starts.
the condition is checked everytime before running code inside the loop. if the condition is false then the loop is exited.
the variable update is done after the first iteration, from the second iteration it is done before the condition check.

Condition in for loop of C

Today I made a typo, and then found below code can be compiled successfully:
#include <stdio.h>
int main()
{
int i;
for (i=0;1,2,3,4,5;i++)
printf("%d\n", i);
}
I don't understand why
1,2,3,4,5
can be treated as a condition?
Your for condition is the expression 1,2,3,4,5. This expression is evaluated using C's comma operator and yields 5. The value 5 is a valid boolean expression that is true, therefore resulting in an infinite loop.
You are using the comma operator. The value of 1, 2, 3, 4, 5 is 5.
More generally, the value of a, b is b. Also, the value of f(), g() is the return value of g(), but both subexpressions f() and g() are evaluated, so both functions are called.
Yes. As others say it's .always true and the comma operator yields 5, hence the loop will repeat infinite times
You can verify it by replacing 5 with 0 . Like this 1,2,3,4,0
Here 0 is false, hence the condition fails.
Yes, 1,2,3,4,5 can be treated as a condition.
The output of 1,2,3,4,5 is 5.
In fact, you need not specify any condition in for loop.
for(;;) is a valid syntax.
A for loop:
for( E1; E2; E3 )
IB
with expressions E1, E2, E3 and an instruction IB is equivalent to a while loop:
E1;
while( E2 )
{
IB;
E3;
}
The only exception is E2, which must be present in while loop condition whilst may be omitted in a forloop condition (and then it is considered equal 1).
So, as others already said, your 1,2,3,4,5 is a comma expression equivalent to a constant 5, making the loop looping infinitely.
See that this code runs... but the for loop continues indefinitely. The condition 1,2,3,4,5 is always verified.
The compiler accepts more that one conditions in for loops. For example:
for(i=0, j=0; i<X, j>y; i++, j--)
//.....
So 1,2,3,4,5 are five conditions (not one) and all these conditions are verified (in fact, these numbers are all different from 0 so they're always true).
// try to know the meaning of condition.
#include <stdio.h>
int main()
{
int i=0;
if(i<=5) // try this
{
printf("%d\n",i);
i++; // increment i
}
}

Condition in a 'for' loop

I am experimenting about what can be put into a for loop declaration in C and how it can be used. I tried the following:
#include <stdio.h>
int stupid(int a)
{
if(a == 3)
return 1;
else
return 3;
}
int main(void)
{
int i, j;
for(i=0; stupid(i)==3,i<10; i++)
printf("%d\n", i);
return 0;
}
When I run the program it just prints the number from 1 to 10, and if I use && instead of comma between the stupid(i)==3 and i<10, then the program just prints the numbers up to 3. Why?
I don't really understand how this works and I was expecting the loop to pass all numbers and "skip" 3, but continue up to 10 and that's not really happening. Why does this happen? Is there some site where this is more clearly explained?
The second clause in the for loop (in your case stupid(i)==3,i<10) is a conditional that is evaluated prior to each entry of the loop body. If it evaluates to true then the loop body is executed. If it evaluates to false then the loop ends and execution continues after the loop body.
With the comma (stupid(i)==3,i<10), the code evaluates stupid(i)==3, forgets the result, and then evaluates i<10, and uses that result for the loop condition. So you get the numbers from 0 to 9.
stupid(i)==3 && i<10 will evaluate to true only if both parts of the expression are true, so when i=3, stupid(i)==3 is false, and the loop exits.
The comma operator evaluates the part before the comma, discards the result, evaluates the part after the comma, and returns that. So in your for loop the part after the comma is i < 10 and this is what is returned as condition for the for loop. That is why it prints the numbers 1 to 10 if you have the comma operator in it.
If you put the && operator in it, it means that both conditions before and after the && have to be met. Otherwise the loop terminates. So if i == 3 the left part evaluates to false and your loop ends.
The comma operator evaluates both, but then overall returns the value of its second operand. Since stupid() doesn't have any side effects, that means nothing much of use really happens here and you're overall just checking to see if i<10.
When you change it to && then both functions must return true (non-zero) for the iteration to continue. On the first pass through, on which the statement evaluates to false, the for loop halts and control continues past it.
The for loop will only continue if the conditions are met. If you place an if statement within the for loop to verify that stupid(i) is equal to three, the for loop will continue.
Using the , operator expands to each line being run. The last line is expected to return a Boolean expression that indicates whether the next iteration should be executed.
In this case, while stupid() does get called, it only checks the return value from the expression i < 10 to decide further execution.
In the for loop, there are three expressions needed, and they are separated by semicolons.
The first is an initializer, and it is run one time before the loop starts. It usually initializes the loop variables.
The second is a condition, and it is run right after the initializer and then before each subsequent iteration. If it is true, the loop statements are run. If it is false, the loop is over.
The third is an expression that is run right after each iteration and right before the condition is checked before the next iteration. It usually progresses the loop by changing the loop variable.
Your condition stupid(i)==3,i<10 uses the comma operator. The comma operator runs each side, but it returns only the value of the right hand side. The value of stupid(i)==3 is completely ignored. The condition stupid(i)==3 && i<10 is true only if both sides are true.
Remember, when the condition is false, the loop is over -- the iteration is not just skipped, the entire loop is over. To get what you want, use
for(i=0; i < 10; ++i) {
if (stupid(i)==3) {
printf("%d\n",i);
}
}
This will go through 0-9, but skip the code if stupid(i) is not 3.
Use:
int main(void)
{
int i,j;
for(i=0; i<10; i++, i+=i == 3)
printf("%d\n", i);
return 0;
}
The limit condition on can only terminate the loop when the condition comes true, not skip iterations. If you want to skip some value, you have to do it at the counting part of for(), or do this with if().
i+=i==3 adds 1 to i when i becomes 3, as i==3 evaluates to 1 if the condition is met and to 0 otherwise (and adding 0 simply does not make any difference).

Resources