C Programming while loops - c

void main()
{
int a;
a=10;
do
while(a++<10);
while(a++<=11);
printf("%d",a);
}
The above program gives an output of 14.
Can you please explain why?

This code will make you understand why , Whenever you type a++ its always incremented
void main()
{
int a;
a=10;
do{
while(a++<10);
printf("%d",a);
}
while(a++<=11);
printf("%d",a);
}

Here your code evaluate as
int main()
{
int a;
a=10;
do{
//---> second iteration a= 12, for post iteration in while
while(a++<10); // First iteration: a=10 ,so false| second Iteration: a=12, so false
//First iteration: Here a=11, as previous line's post increment| Second iteration: here a=13, as previous post increment
} while(a++<=11); //First iteration: a==11, that evaluete true, go to --->, line after do | Second iteration: a=13, false, loop end goto next line
//Here a=14 for post increment in previous line's while loop
printf("%d",a); // a=14
}
In post increment first evaluate the expression with current value then increment the value of the variable.
For example in second iteration when program start execution on outer while while(a++<=11), this time a=13 as previous value of a. This a++<=11 execute and return 0 which makes while(0) (Because a=13, which is greater than 11). Then increment occur and a becomes 14. As while(0) it break the do-while loop and goes to next instruction and print the value 14.

Oh, this is evil. Reformatting the code a bit should show what's happening:
a=10;
do
{
while(a++<10);
}
while(a++<=11);
So. a is initially set to 10. We enter the do while loop. The only statement in the do while loop is while( a++ < 10 );. Remember that the expression a++ evaluates to the current value of a, and as a side effect increments a.
So, a++ < 10 is evaluated. The result is false (10 is not less than 10), but as a result of evaluating the expression, a is incremented and now has value 11. At the end of the do while loop, we evaluate a++<=11. This evaluates to true since a currently has the value of 11. As a result of evaluating the expression, a is incremented to 12.
We execute the body of the do while loop again. The expression a++ < 10 is evaluated again. Like before, the result is false, but as a result of evaluating the expression a is incremented to 13.
We then evaluate a++ <= 11 again. The result is false, since 13 is not less than or equal to 11, and a is incremented one more time.
Thus, by the time this whole mess is finished, a is 14.
Summarizing:
a is initially 10;
do while loop is entered
a++ < 10 is evaluated, a is now 11
a++ <= 11 is evaluated, a is now 12, do while loop repeats
a++ < 10 is evaluated, a is now 13
a++ <= 11 is evaluated, a is now 14, do while loop exits.

Curly braces would make it more readable, but as you have it, the execution flow and values of a are explained in line:

Well the post increment will only happen after the condition is evaluated so a will get incremented even if the condition is false and may add more runs of the loop then you are expecting.

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

Strange behaviour of a variable increase in a for loop

EDIT: this is not my code, that's a part of a exam.
This is the output:
60 -3 //from -5 to -3
59 0 //from -3 to 0
58 3
57 6
2
I can't figure out why in the first loop, the 'i' variable was increased two times and in the second loop three times.
int a=61,i=-5;
for(int *p=&i;(a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1);(*p)++){
--a;
printf("%d %d \n",a,*p);
if(*p>3){
a=(!(--a)&&a++)?3:2;
break;
}
else continue;
}
printf("%d\n",a);
The only sensible thing to do with code like this (except from saying words that are not allowed here to the author) is to rewrite it. The else continue can be removed. It accomplishes nothing.
Then we go for the beast (a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1). This will be executed in the beginning of each loop, so we can rewrite it like this:
bool cond = (a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1);
for(int *p=&i; cond; (*p)++){
cond = (a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1);
--a;
printf("%d %d \n",a,*p);
if(*p>3){
a=(!(--a)&&a++)?3:2;
break;
}
}
Now when it's removed from the header, we can start disassemble it. First, exctract a++ change to if statements:
a++;
if((*p)++)
cond = (++(*p),(a--)-1)
else
cond = ((*p)+=3,a-1);
It's already looking a lot clearer. Now, lets get rid of those commas:
if((*p)++) {
++(*p);
cond = (a--)-1;
}
else {
(*p)+=3;
cond = a-1;
}
Let's continue the separation
if((*p)++) {
(*p)++; // Does not make a difference here, but it's easier to not mix pre and post
a--;
cond = a;
}
else {
(*p)+=3;
cond = a-1;
}
That's about as far as we get by just mechanically breaking it down. To get further we would need to think a little bit. So let's continue to the next, which is a=(!(--a)&&a++)?3:2; and we will simplify it too.
--a; // Will be executed no matter what
if(!a) {
a++; // Will only be executed if !(--a) evaluates to true
a = 3; // But it does not matter since we are reassigning a
} else {
a = 2;
}
This will give this code after simplification.
bool cond;
a++;
if((*p)++) {
(*p)++;
a--;
cond = a;
} else {
(*p)+=3;
cond = a-1;
}
for(int *p=&i; cond; (*p)++){
a++;
if((*p)++) {
(*p)++;
a--;
cond = a;
} else {
(*p)+=3;
cond = a-1;
}
--a;
printf("%d %d \n",a,*p);
if(!a) {
a = 3;
} else {
a = 2;
}
}
printf("%d\n",a);
Now it's actually possible to reason about it, and it should be fairly easy to just execute this code on paper step by step.
The (*p)++ statement at the end of the for loop declaration will not be executed on the first iteration. It gets executed only between two consecutive iterations.
First, int a=61,i=-5; gives us a = 61 and i = −5.
Then the initial clause of the for, int *p=&i, sets p to point to i. From this point on, we may take *p as equivalent to i.
Then the controlling expression of the for, (a++,(*p)++)?(++(*p),(a--)-1):((*p)+=3,a-1), is evaluated. Its highest/outermost operator is ? :. The first operand of that (a++,(*p)++) is evaluated. This sets a to 62 and i to −4. The result, from the comma operator, is the value of i (*p) before the increment, so it is −5.
That −5 is used to select in the ? : operation. Since it is not zero, the operand between ? and : is evaluated. That is (++(*p),(a--)-1). This sets i to −3 and a to 61. The value is a before the increment minus 1, which is 62−1 = 61. Thus the expression is non-zero, indicating the loop should continue.
Program control flows into the body of the for, where --a decrements a to 60.
Then the printf shows us that a is 60 and i is −3.
The test *p>3 is false, since i is −3, so the continue is executed.
This causes the iteration expression of the for to be evaluated. That is (*p)++, so i is set to −2.
Then the controlling expression is evaluated. As before, the first operand of ? :, (a++,(*p)++), is evaluated. This sets a to 61 and i to −1, and the value of the expression is −2.
Again the second operand,(++(*p),(a--)-1), is evaluated. This sets i to 0 and a to 60, and its value is 59.
Inside the body, --a decrements a to 59.
The printf shows us a is 59 and i is 0.
Again *p>3 is false, so the continue is executed.
This takes control to the iteration expression, (*p)++, which sets i to 1.
Then the controlling expression is evaluated, starting with the first operand of ? :. Now (a++,(*p)++) sets a to 60 and i to 2, and the expression value is 1.
The second operand of ? :,(++(*p),(a--)-1), is evaluated, which sets i to 3 and a to 59, and the expression value is 59, so the loop continues.
--a sets a to 58.
The printf shows us a is 58 and i is 3.
Again *p>3 is false, so the continue is executed.
This takes control to the iteration expression, (*p)++, which sets i to 4.
Then the controlling expression is evaluated, starting with the first operand of ? :. Now (a++,(*p)++) sets a to 59 and i to 5, and the expression value is 4.
The second operand of ? :,(++(*p),(a--)-1), is evaluated, which sets i to 6 and a to 58, and the expression value is 58, so the loop continues.
--a sets a to 57.
The printf shows us a is 57 and i is 6.
Now *p>3 is true, so the statements inside the if are executed.
These start with a=(!(--a)&&a++)?3:2;. Here --a sets a to 56 and evaluates to that value. Then ! inverts it logically, producing 0. This causes the && to produce 0 without evaluating its second operand. So this first operand of ? : is 0, which results in the third operand of ? : being evaluated. That operand is 2, so that is the value assigned to a.
The final printf shows us the current value of a, 2.

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.

How is the output to the code 9?

#include <stdio.h>
int main()
{
int i=0;
while(i++,i<=8);
printf("%d\n",i);
return 0;
}
Why is the increment of i done after the comparison in each test case?
i <= 8 succeeds for the last time when i = 8.
In the last iteration, i++ is executed, then i <= 8 fails because i = 9.
Note that the , is a sequence point, so i++ is absolutely guaranteed to be executed before i <= 8. Not so for similar constructs.
It's not. Your loop condition is i <= 8, it is first non-true when i reaches 9 (you're incrementing i by 1 each time, so it will be exactly 9). That is why it prints 9.
To reach to the print() statement, while loop must end. The terminating condition, controlling expression should evaluate to false (or, in other words, until the controlling expression compares equal to 0), i.e., it will be false only when i <= 8; evaluates to false. For a value of i as 9, that happens.
Next line, the value of i, gets printed. So, you see 9.
Increment of i is not done after the comparison in each test case. i++ is executed first and after that the comparison is done.
This is because when expressions are separated using commas in C, the expressions are evaluated from left to right and the value of the last expression becomes the value of the total comma separated expression.
So the value of
i++,i<=8
is actually the value of i<=8 and that comparison is done only after i++ is executed.
So the while loop here
int i=0;
while(i++,i<=8);
is equivalent to
for(i=1; i<=8; i++);
Hence the control exits the loop only when i is greater than 8. Since i is incremented by 1 on each iteration, this means that the loop is over when i becomes 9.
You started i = 0 and using while ( i++, i<=8 ) loop you incremented it's value until 8 and when it's increased one more time i = 9 , then loop condition became false and breaks the loop with i = 9. And that's why now, when you print i's value, it gave you 9.

Increment operation as a parameter in while loop

#include <stdio.h>
#include <string.h>
main()
{
int a;
a=1;
while(a++<=2)
;
printf("%d",a);
}
This code gives the output as 4.
How is a getting incremented?
How does a++ work?
First things first, let's understand what happens when you type a++. What you are using is called a post increment operator. To explain its behavior, one can look at the "verbose equivalent":
prev_a = a;
a = a + 1;
return prev_a;
Note that the value returned by the a++ expression is the value it had before the increment.
On the other hand, if you had written ++a, you would be using a pre increment operator, which returns the value after increment. Kind of like:
a = a + 1;
return a;
So when you write a++ <= 2, you are comparing the current value of a, and incrementing it "after comparison", for the next iteration.
How does while work?
Now when you write something like while (expr) { /* ... */ }, what happens is that expr is evaluated before every iteration, and the iteration actually runs only if the result of the expression is true.
So what happens?
First iteration
a is equal to 1;
it is smaller or equal to 2: we decide go for another iteration;
increment a;
Second iteration
a is equal to 2;
it is smaller or equal to 2: we decide go for another iteration;
increment a;
Second iteration
a is equal to 3;
it is not smaller or equal to 2: we decide to stop after this iteration;
still increment a, as part of "evaluating the whole expression a++ <= 2";
In the end, a is equal to 4.
I guess what tricked you is the fact that the previous value of a (before increment) is used for comparison, but that the increment does always happen as part of the expression. a is being incremented, even if the comparison returns false!
In the end, your code is equivalent to:
int a;
a = 1;
int prev_a;
while(true) {
prev_a = a; // the previous value is saved for the comparison
a = a + 1; // the increment ALWAYS happen
if (prev_a > 2) {
break;
}
}
When a=3 we have a++<=2 i.e. 3++<=2 - hence it becomes 4 at the end of the statement even though the condition fails. You could have simply put a printf to check this:
while(a++<=2)
{
printf("%d ",a);
}
After 2 iteration the value of a is 2. So the condition is true and the value is incremented again i,e a=3.
Now the while condition is checked again and it returns false. But a is incremented again as (3++<=2) so a=4
Because the condition of the loop (a++<=2) evaluated by 3 times.
1st time: a is 1, and a <= 2, and then a -> 2 by operator++
2nd time: a is 2, and a <= 2, and then a -> 3 by operator++
3rd time: a is 3, and a not <= 2, and then a-> 4 by operator++
How is a getting incremented?
a is increased by the a++ in while(a++<=2);.
a++ will return the value of a and add one to it, so when a is 3, a++<=2 will be false, but a still get added by one.
init_stat execute status result
a =1 while(a++<=2) success a =2
a =2 while(a++<=2) success a =3
a =3 while(a++<=2) fail a =4

Resources