Why is this not a infinite loop? - c

int main() {
int i,j=6;
for(;i=j;j-=2)
printf("%d",j);
return 0;
}
This piece of code gives output 642
please explain me why this loop doesn't run infinitely and stops when j is non-positive

When j becomes 0 the expression i=j evaluates to 0. Hence, the loop terminates.
Note that if j were to start as negative number ( e.g. -1 )or as an odd number (e.g. 5), then the condition will never evaluate to 0 and will result in an infinite loop.

In C 0 is evaluated as false and non-zero as true. The controlling expression i = j becomes false when j = 0 and the loop will terminate.
The loop will go infinite if you change your program to
int i, j = 6;
i = j;
for(; i == j; j -= 2, i = j)
printf("%d",j);

for(;i=j;j-=2)
This is a for loop with no initial code, which on every iteration will assign j to i as the condition check, then at the end decrement j by 2. Note that the value of an assignment expression is the value assigned, hence your i = j expression will yield the value of j.
So, what will happen cycle by cycle is as follows:
Assign i = 6, j = 6
Nothing for the initial for loop statement
i = j (6)
Print j (6)
j -= 2
i = j (4)
Print j (4)
j -= 2
i = j (2)
Print j (2)
j -= 2
i = j (0)
The above expression evaluated to 0, hence false, hence the loop terminates.

Related

How does 'for' work when all of its "parts" are 'i++'?

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.

Can anyone tell me why this program runs? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
New to c programming. Here is a question from an assignment. Can anyone tell me why this code still outputs two columns 5 and 2 even though i is less than j.
#include <stdio.h>
int main(void) {
int i = 0, j = 5;
for (i > j; i + j == 5; j < 2) {
printf("Two columns\n");
i = 5;
j = 2;
}
printf(" %d %d\n", i, j);
return 0;
}
Here are the steps executed in order:
int i = 0, j = 5; local variables i and j are defined and initialized to 0 and 5 respectively
for (i > j; i + j == 5; j < 2) {:
first executes the initial expression i > j which evaluates to false (0) and has no side effect, the result is ignored, hence probably completely omitted by the compiler.
second executes the test expression i + j == 5 which evaluates to true (1) so the body of the for loop executes.
printf("Two columns\n"); outputs Two columns and a newline.
i = 5; sets i to 5.
j = 2; sets j to 2.
} the increment expression is then evaluated: j < 2, which evaluates to false but has no side effect, the result is ignored.
the loop then evaluates the test expression again: i + j == 5 which now evaluates to false (0) since 5 + 2 is different from 5.
the loop exits.
printf(" %d %d\n", i, j); outputs the numbers 5 and 2 and a newline as you observe.
return 0; main returns the value 0 which is a successful exit status.
This code is very silly and purposely misleading as it has test expressions in all 3 parts of the for statement header. Only the middle one is the test expression, the first and last expressions are only used for side effects, such as initializing and incrementing a loop counter.
for (i > j; i + j == 5; j < 2)
In for loop initialization part i > j no make sense
Then i + j == 5 condition become true and executed for loop body where assigned new values to i and j respectively 5 and 2.
Then control goes to for loop increment part where j < 2 become false. this is also no make sense.
Then again control goes to condition part where i+j == 5 becomes false because i is a 5 and and j is a 2. So, 7 == 5 becomes false.
So, output of your code is 5 and 2.

Why does this second loop have no initialization? And why does it print five stars?

This program produces this output:
*******
*****
***
*
Here's the code:
#include <stdio.h>
int main(void)
{
int i, j;
for (i = 1; i <= 5; i++)
{
for (j = 1; j < i;j++)
printf(" ");
for (; j <= 8 - i;j++)
printf("*");
printf("\n");
}
return 0;
}
What's the meaning of for (; j <= 8 - i;j++)? There is no initialization step and also don't understand why there is only five * on the second line.
For loops don't actually need to have an initialization statement. Many loops choose to include one, but it's not strictly necessary. Consequently, you can think of that loop as saying "we don't need to do anything special here for initialization."
As for why there are five stars on the second line, let's look at this part of the code:
for (j = 1; j < i;j++)
printf(" ");
for (; j <= 8 - i;j++)
printf("*");
On the second iteration, i is equal to 2. When the first loop runs, it will print out a single space character. The loop stops running when j < i is no longer true, so when it finishes running, the value of j will be 2. Therefore, the second loop will run for j =2, 3, 4, 5, 6, stopping when j = 7. That's why you see five stars.
Hope this helps!
What's the meaning of for (; j <= 8 - i;j++)?
That for takes the last (known) value of j used in the program
for (; j <= 8 - i;j++)
printf("*");
Here there is no need for initialization of j as value of j comes from previous for loop.
First case i=1 and j=1 but condition in loop is false and j increments to 2. And this value goes in innermost loop which runs till j=7.
That loop is using the j variable from the for loop directly above it. Each iteration of it is shorter by 2; one from the beginning, and one from the end. That is how it maintains the text centrally on the screen.
So, the first iteration at i=1 will not print any " ". It will then print 7 *, from j values of 1-7.
The second iteration at i=2 will print one " ", followed by 5 *, from j values of 2-6.
Each iteration subsequently follows this pattern.
Okay, j is initialized in the outer most block with respect to the for loops so now j is accessible from all the for loop (or any other loop).
it uses the last modified(incremented) value by the outermost for loop.
i think you can figure it now .
just figure out it by using copy pen and create a matrix for the for loop variables.
it will surely improve your programming skills.
Happy Coding.
you can try this:
variations in for loop in C
#include <stdio.h>
int main(void)
{
int i, j;
for (i = 1; i <= 5; i++) **1**
{
for (j = 1; j < i;j++) **2**
printf(" ");
for (; j <= 8 - i;j++) **3**
printf("*");
printf("\n");
}
return 0;
}
You will find that the variable j does not need to be initialized in loop 3 as it has been initialized in loop 2, and it is within the scope of the local block (j exists within loop 1, and need'nt to be initialised after loop 2).
With regard to your second query,
consider the second iteration of loop1 where i=2. When loop2 completes its execution at this point, j=2. Now consider loop3, where j is 2 (as previously established) and it executes until j is less than or equal to 8-i(8-i=8-2= 6).
So it prints a star for j = 2,3,4,5,6 = 5 stars.
Replace
printf("*");
by
printf("%d", j)
and look how the value of j is changing. This could explain how it works.

What does "for (; --i >= 0; )" mean in C?

What does for (; --i >= 0; ) mean in C?
How is the counter getting decremented and how is it different from for ( ; i >= 0; --i)?
They are very similar, but not the same! First you have to understand how a for loop in C gets executed:
As an example:
1 2, 5 4
| | |
v v v
for(i = 0; i < 5; i++) {
// Do something <-- 3
}
As you can see 2, 3, 4, 5 is a loop until the condition is false.
Now you should clearly see how the for loop gets executed. The difference now is that in your first example:
int i = 5;
for ( ; --i >= 0; )
printf("%d\n", i);
The output would be:
4
3
2
1
0
Because after the first check of the condition (Point 2), it executes the code block of the for statement and i already gets decremented.
In your second example:
int i = 5;
for( ; i>=0; --i)
printf("%d\n", i);
The output would be:
5 // See here the difference
4
3
2
1
0
Here you get the difference, because it gets decremented in Point 4, so the first time it runs with the value 5.
These constructs are formally equivalent to
while (--i >= 0)
{
Body;
}
and
while (i >= 0)
{
Body;
--i;
}
Do you better see the difference?
In general, we can convert any for loop or while loop into a set of mostly linear statements with a goto. Doing this may be helpful to compare the code.
Case 1
### for (; --i >= 0; ) { statements; }
; // Initializer statement
start:
bool condition = (--i >= 0); // Conditional
if (condition) { // If true, we execute the body as so:
statements; // The statements inside the loop
; // Empty increment statement
goto start // Go to the top of the loop.
}
Case 2
### for( ; i>=0; --i) { statements; }
; // Initializer statement
start:
bool condition = (i >= 0); // Conditional
if (condition) { // If true, we execute the body as so:
statements; // The statements inside the loop
--i; // Increment statement
goto start; // Go to the top of the loop.
}
Let's compare the "simpler" code from those two cases.
In the first case, we decrement i for the first time before each loop body. In the second case, we decrement i after each loop body.
The easiest way to see that is to consider what happens when you enter this loop when i == 0. In the first case, after this block of code, you would have a resulting value of i == -1. In the second case, i wouldn't have changed (that is, i == 0), because we never reached the increment statement.
for (; --i >= 0; ) works like this:
Say if you have i as 10, it will decrement the i value and will compare 9 >= 0 and so on.
So the output would be like 9, 8... till 0.
While the loop for( ; i>=0;--i) would first go to 10, then decrement the value and then it would check i>=0. So the output would be 10, 9, 8... till 0.
The first one decrements i and then checks the condition.
The second one checks the condition first and if true, decrements i after the loop body has been executed.
Well, it is the same as saying for( i=0 or some value; --i <= 0 ; do nothing){}
and --i is an predecrement operator.
That means when this piece of code, i.e., --i, is being read, the value of i will decrease by 1 at the same moment.
There are three main components in a for loop.
Initialization, condition, and afterthought.
Initialization happens once at the start of the entire statement. Condition happens before every cycle. Afterthought comes after every cycle. Consider i starts at 2:
for (; --i >= 0; )
Initialization: i = 2
Condition: i = 1
Afterthought: i = 1
Condition: i = 0
Afterthought: i = 0
Condition: i = -1
Exit
In the other case
for( ; i>=0; --i)
Initialization: i = 2
Condition: i = 2
Afterthought: i = 1
Condition: i = 1
Afterthought: i = 0
Condition: i = 0
Afterthought: i = -1
Condition: i = -1
Exit
You can see that the second version actually lasts one cycle longer!
The three parameters (initialization, condition and increment) in for are optional (but they still requires the semicolon ;). So, you can safely write for(;;) and it's the same as while(1). So, expressions like
for(; x > y; x++) { ... }
for(;1;x++) { if(x > y) break;
for(;;) { if(x++ > y) break;
for(;x++ > y;) { ... }
Are valid and equivalent. In this, the increment occurs in the conditional parameters, just like in your code example.

Understanding multiple conditions in a C loop

There is a piece of C code
int i, j = 0;
for (i = 0, j = n-1; i < n; j = i++) {
// array operations
}
that I'm trying to convert into Lua code
local j = n-1
for i = 1, n do -- arrays are 1-based in Lua
-- array operations
j = i+1
end
but for some reason Lua code doesn't work. Am I getting that C loop right?
Imagine an array as a circular buffer. i is the current item and j is always the previous one:
n = 5
local j = n
for i = 1, n do -- arrays are 1-based in Lua
-- array operations
io.write('i=', i, ' j=', j, '\n')
j = i
end
Demo:
i=1 j=5
i=2 j=1
i=3 j=2
i=4 j=3
i=5 j=4
I do not know Lua but what the C code does is:
At every iteration:
Assign i to j: j = i;
Then increment i by 1: i = i+1;
Looks like your Lua code should be j = i instead of j = i+1
No, j is always one less than i unless i equals 0, then j is n-1. So j = i+1 should probably be j = i as i will be increased in the next iteration.
I don't know Lua so I can't be sure.
Probably not best to transform it into a lua for loop; use a while loop:
local i , j = 0 , n-1
while i < n do
--array operations
j = i
i = i + 1
end
Not that the code makes alot of sense.... if you want to convert to 1 based indexing as well use i , j = 1 , n and i<=n

Resources