Strange output when using do/while in C programming lang - c

I am trying to understand the output of this program.
If I try to "translate" the code, I believe it should go like this:
while "j" is smaller than 3 - print "Ha" (this loop goes 3 times, so it gives 3 "Ha")
do/while -> j is equal to j - 2 hence print "Hi" while ++j - In the end the program prints out "Hi" 4 times.
How does the program prints it 4 times, how does the condition works here?
#include <stdio.h>
int main() {
int j = 0;
while(j++ < 3){
printf( "Ha ");
}
do{
j -= 2;
printf( "Hi ");
}
while(++j);
for(j = 1; j <= 3; j++){
printf( "Ho ");
}
printf("\n");
return 0;
}
The output is:
Ha Ha Ha Hi Hi Hi Hi Ho Ho Ho

The ++j is prefix increment, i.e., the value will be increased and then, the incrased value will be used for the condition check.
I have added a print statement for the ease of understanding:
do{
j -= 2;
printf( "Hi ");
printf("value of j before the while = %d\n", j);
}
while(++j);
and the output is:
Hi value of j before the while = 2
Hi value of j before the while = 1
Hi value of j before the while = 0
Hi value of j before the while = -1
So, in the
first iteration, in while (++j), j is 2, and ++j is 3
second iteration, 3-2 = 1, and ++j is 2.
third iteration, 2-2 = 0, and ++j is 1.
Fourth iteration, 1-2 = -1, and ++j is 0 - this make the while chec false and the loop ends.

After the first while loop
while(j++ < 3){
printf( "Ha ");
}
j is equal to 4.
So within the first iteration of the do-while loop
do{
j -= 2;
printf( "Hi ");
}
while(++j);
j is equal to 2. After the first iteration j is equal to 3. Within the second iteration j is equal to 1. After the second iteration j is equal to 2. Within the third iteration j is equal to 0. After the third iteration j is equal to 1. Within the forth iteration j is equal to -1. So in this forth iteration in the condition
while(++j);
j is equal to 0 and the control is passed to the next loop.
So the do-while loop was executed 4 times.
That is the value of the postfix increment operator is the value of its operand before incrementing. And the value of the pre-increment operator is the value of its operand after incrementing.

After first loop
j == 4
j -= 2 == 2
Hi
++j == 3
j -= 2 == 1
Hi
++j == 2
j -= 2 == 0
Hi
++j == 1
j -= 2 == -1
Hi
++j == 0 //end of th loop

The best way to understand what your program does is to watch the value of j at each step of your program.
first j=0
then you enter into the while.
j=0 ; j<3? ; yes ; j=j+1 ; it print "Ha".
j=1 ; j<3? ; yes ; j=j+1 ; it print "Ha".
j=2 ; j<3? ; yes ; j=j+1 ; it print "Ha".
j=3 ; j<3? ; no ; j=j+1 ; leave the while statement
j=4
then you leave the while to enter into de do, while() statement. at this moment j=4.
in the do , while() :
j=j-2 ; j=2 ; it print "Hi" ; j+=1 ; j=3; j!=0 ? yes
j=j-2 ; j=1 ; it print "Hi" ; j+=1 ; j=2; j!=0 ? yes
j=j-2 ; j=0 ; it print "Hi" ; j+=1 ; j=1; j!=0 ? yes
j=j-2 ; j=1 ; it print "Hi" ; j+=1 ; j=0; j=0 ? no -> leaving the do while()
at the end you enter in the for statement.
++x is called Pre incrementation (the variable is incremented before the expression evaluation)
x++ is the post incrementation (the variable is incremented after the expression evaluation
i'm not sure about this, you need to check this informations.

Related

initializing counter outside for loop doesn't work as intended

the following two programs are supposed to produce all three digit combinations of 1, 2, 3 (with repetition). They are identical in every way, other that where the loop counters are being initialized
#include <stdio.h>
int main(void)
{
short i, j, k;
i = j = k = 1;
for (; i <= 3; i++) {
for (; j <= 3; j++) {
for (; k <= 3; k++)
fprintf(stdout, "%hi %hi %hi\n", i, j, k);
}
}
return 0;
}
...This one where the counters for the three loops are being initialized outside them doesn't produce the desired output. It prints.
1 1 1
1 1 2
1 1 3
The second one...
#include <stdio.h>
int main(void)
{
short i, j, k;
for (i = 1; i <= 3; i++) {
for (j = 1; j <= 3; j++) {
for (k = 1; k <= 3; k++)
fprintf(stdout, "%hi %hi %hi\n", i, j, k);
}
}
return 0;
}
...where the counters are being initialized within each loop, produces the desired output
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Read in a book that a for loop can be written in several forms--all of which are identical--and that the counter can be initialized, incremented, tested either inside or outside the for statement. Then why the different behavior here?
Because you don't initialize the variables i, j, k inside the loop but define them in the outer scope, their values remain saved.
In particular k remains 4, after the first loop finishes to run, then the condition k<=3 is always false and the print statement is never reached.
To write the code in the equivalent way to your book meant is that way:
#include <stdio.h>
int main(void)
{
short i, j, k;
i = 1;
for (; i <= 3; i++) {
j = 1;
for (; j <= 3; j++) {
k = 1;
for (; k <= 3; k++)
fprintf(stdout, "%hi %hi %hi\n", i, j, k);
}
}
return 0;
}
In the second one, the variables j and k are reinitialised to 1 each time the for loop is encountered.
In the first one, they are always just left with the value that they had - which means that the second time round (when i == 2 or 3), j is left at 4 from the first time round, which immediately fails the j <= 3 condition.
it's not about how you initialize the for loop, but the fact that each time that you start the for loop you don't initialize it.
for (; i <= 3; i++) {
for (; j <= 3; j++) {
for (; k <= 3; k++)
so for the first time it's fine since the values are correct, but after the 2nd and 3rd for loop finished their iterations and the first for loop reached the 2nd index the other for loops are not being initialized so their values remain 4 and the condition isn't being met, so the loops stop there.
you still need to use the initialization inside the nested for loops regardless to fix the issue.
If you initialize your variables just once, outside the for loops, then their values will never get re-initialized in the nested loops (something you need in order to generate every combination starting with 1xx, 2xx and 3xx).
In the case of the outside initialization:
After you've generated all the 11x combinations, your k variable will have the value 4, regardless of what the enclosing loops do.
So when either j or i increments to 2 and 3, your k will already be 4, hence the innermost for loop will not execute anymore.
Needless to say, the second variant of your code, re-initializes k and j every time i increments, which will then make your code reach the printf every time like you intended.

Assignment and Conditional check in C

I came across this below program and I don't understand the output.
Can someone please shed some light on it?
#include <stdio.h>
int main()
{
int i=1,j=1;
for(;j;printf("%d %d\n",i,j))
j=i++ <=5;
return 0;
}
And its output is:
2 1
3 1
4 1
5 1
6 1
7 0
#include <stdio.h>
int main()
{
int i=1,j=1;
//for(initialisation; condition; operations)
// here no initialisation,
// 1. condition is j, if j is true
// 2. then it will execute block statements
// 3. then finally it execute operations, here printf
// 4. again check step 1.
for(;j;printf("%d %d\n",i,j))
j=i++ <=5; // j = (i <= 5); i++;
return 0;
}
Your question can be simplified as follows
#include <stdio.h>
int main()
{
int i=1,j=1;
while(j) {
j = (i++ <=5);
printf("%d %d\n",i,j);
}
return 0;
}
As Ajay have given an alternative code to the original one (I'll copy-paste it below for convenience)
#include <stdio.h>
int main()
{
int i=1,j=1;
while(j) {
j = (i++ <=5);
printf("%d %d\n",i,j);
}
return 0;
}
Now, let's look at the execution of the while loop
i=1, j=1, j is True, in loop, j = (1 <= 5) = true = 1, i=2 (post increment).
i=2, j=1, j is True, in loop, j = (2 <= 5) = true = 1, i=3 (post increment).
i=3, j=1, j is True, in loop, j = (3 <= 5) = true = 1, i=4 (post increment).
i=4, j=1, j is True, in loop, j = (4 <= 5) = true = 1, i=5 (post increment)
i=5, j=1, j is True, in loop, j = (5 <= 5) = true = 1, i=6 (post increment).
i=6, j=1, j is True, in loop, j = (6 <= 5) = false = 0, i=7 (post increment).
i=7, j=0, j is False, out of loop.
Program Stops.
Hope this execution explanation helps.
The following statement:
j=i++ <=5;
evaluates the value of the variable i before incrementing it. This evaluated value is used in the comparison <= 5. The result of a comparison will be either 0 or 1 depending whether the condition is false or true respectively.
In this case, it has the same effect as writing it in two separate statements:
j = i <= 5;
++i;
syntax of for loop:
for (initialization Statement; check condition; increment/decrements operation)
{
// codes
}
The initialization statement is executed only once. Then, the check condition is evaluated. If the condition is true (nonzero), then codes inside the body of for loop is executed and the update expression is updated. if condition is false(0), then for loop terminated.
In your code,
j = 1 then condition become true and enter into body of for loop. Then, check
j = i++ <= 5 = true, and control goes to increment/decrements operation part and print i = 2 and j = 1.
then, again code repeated until the test condition is false.
Same can be represent in this manner:
#include <stdio.h>
int main()
{
int i,j;
for(i=1,j=1;j!=0;){
j=i++ <=5;
printf("%d %d\n",i,j);
}
return 0;
}
here, as per convention of for loop.
i & j is initialized to 1
check condition whether j != 0
i <= 5 so j remains 1 && i becomes 2 (after increment)
prints i = 2, j =1
again, i <= 5 so j remains 1 && i becomes 3 (after increment)
prints i = 3, j =1
again, i <= 5 so j remains 1 && i becomes 4 (after increment)
prints i = 4, j =1
and this goes on, it j becomes 0, as it violent the condition as i becomes greater than 5

Program that sums things to an array

This book requires me to answer '' What output do you expect from the following program?''
After reading it many times I dont seem to fully understand its inner workings.
From what I get:
First For loop stablishes that this process is going to repeat for 10 times. Variable j is assigned to start at 0.
Second for loop starts the variable i at 0 and stablishes the condition i < j and does the operations written after it.
What is going on exactly? j starts at 0 and so does i, therefore numbers[j] += numbers[i] equals 2?
What happens after this operation is completed?
If i and j equal to 0 then why is this condition i < j True?
int main (void)
{
int numbers[10] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int i, j;
for ( j = 0; j < 10; ++j )
for ( i = 0; i < j; ++i )
numbers[j] += numbers[i];
for ( j = 0; j < 10; ++j )
printf ("%i ", numbers[j]);
printf ("\n");
return 0;
}
The first thing you have to notice is that you have the outer loop, which runs from 0 to 10 and you to something to numbers[j]. This indicates that you take each element and modify it somehow. In order to find how, by inspecting the second loop and the right hand side of the assignment, you can notice that it adds to numbers[j] all elements with indices smaller than j. Now let's see what happens in a few steps:
j = 0 : 1 0 0 0 0 0 0 0 0 0
j = 1 : 1 1 0 0 0 0 0 0 0 0
j = 2 : 1 1 2 0 0 0 0 0 0 0
j = 3 : 1 1 2 4 0 0 0 0 0 0
j = 4 : 1 1 2 4 8 0 0 0 0 0
At the end, you will get an array with the property that each element a[j] is equal to a[0] + a[1] + ... + a[j] and a[0] = 1.
Now, taking a closer look at the beginning of the process, you have j = 0 and i = 0. The second for loop runs for as long as i < j. Since this comparison is false, the loop is not executed and we go to the next iteration of the outer loop, with j = 1.

What does "<" do here in the expression j = i++ < 5 do?

What does the operator < (less-than) do?
Also, can you explain why did for-loop ended?
main()
{
int i = 1, j = 1 ;
for ( ; j ; printf ("%d%d\n", i,j))
{
j = i++ < 5 ;
}
return 0;
}
I got the output as
21
31
41
51
60
The code checks if i is smaller than 5, then increments i. The result of the comparison is stored in j.
It is quite an obscure way to make a loop like this. Not very readable.
It returns 1 if i is less than 5, otherwise it returns 0. Note that increment does not affect the comparison, until the next loop iteration.
when your loop is executing i++ it is actually incrementing the value of i . The condition
j= i++ < 5 will check for the return value '1' or '0' so when accordingly your output print statement printf ("%d%d\n", i,j) will print
i=2 ; j=2<5 -> return 1 so print (2,1)
i=3; j=3<5 -> return 1 so print (3,1)
and so on till the condition becomes false and your output is finally j=return '0' for i=6
this will give you ans (6,0)

Why does this program not give the expected output?

This program (in C) doesn't output what I'd expect:
int main()
{
int i, j ;
for ( i = 1 ; i <= 2 ; i++ )
{
for ( j = 1 ; j <= 2 ; j++ )
{
if ( i == j )
continue ;
printf ( "\n%d %d\n", i, j ) ;
}
}
}
I think it should be
1 2
1 3
2 1
2 3
But the program outputs
1 2
2 1
Why is this?
Number 3 cannot be ever reached by the loops' indices.
The values of i and j go through this sequence:
i j
---
1 1
1 2
2 1
2 2
Note that the i++ and j++ increments happen after each iteration of the loop body.
The only cases where your printf is called are where i and j are different. That means you get:
1 2
2 1

Resources