why in my code second "for" in function loop only once - c

i wrote this nested "for" program but second loop only work once and print one row of "x"
#include <stdio.h>
void draw_box(int , int);
int main(int argc, char **argv)
{
draw_box(8 , 35);
return 0;
}
void draw_box(int row , int column)
{
for(;row>0;row--)
{
for(;column>0;column--)
printf("X");
printf("\n");
}
}

The second loop functions only once because it runs the value of column into zero, and never resets it back to the original value passed in as a parameter:
for(;row>0;row--) {
int origColumn = column; // Save the value
for(;column>0;column--)
printf("X");
column = origColumn; // Restore the value
printf("\n");
}
This illustrates why one should be very careful when modifying values passed to your function as parameters. Your function would be as easy to write and easier to read with loop variables:
for(int r = 0 ; r != row ; r++) {
for(int c = 0 ; c != column ; c++)
printf("X");
printf("\n");
}

The problem here is that, your second loop iterates to zero and was never rest to its original value. You can either assign the value to a temporary variable and use that for iteration, and at the closing of the second "for" loop, set the temp value back to the default value OR You could change the for loop structure by assigning a variable j=0, and iterating it over and over again until it does not satisfy the condition j
The first for loop does not face this problem because, when you enter the firs for loop, the second for loop is executed "column" number of times before the control goes back to the first for loop.

When you are using nested for loops
for(;row>0;row--)
{
for(;column>0;column--)
printf("X");
}
For each value of row , you are iterating through entire column.
So, X is printed the number of column times.
But value of column is reduced to zero each time you iterate through outer loop.
For clarification consider inner loop :
If value of column is 5,
X is printed and the value of column reduces to 4.
Similarly, X will be printed 5 times and at that moment, value of column reduces to zero
Now, for the second iteration of outer loop, value of column remains zero and it will not pass the inner loop condition. Thus your pointer will not move inside the second loop to print X .
How to overcome this : Use loop-variable.
Now every time you iterate through inner loop, value of loop-variable will be reduced and not of column.
So, while iterating through through outer loop second time, value of loop-variable will be restored to value of column and then X could be printed column number of times(in this case 5).
Solution :
for(i = 0; i < row; i++){ //Good habit to start from 0, as it is
for(j = 0; j < column; j++){ //useful when you are working with matrix
printf("X");
}
printf("\n");
}

Related

Can someone help me understand the execution of this C program? (Beginner)

#include <stdio.h>
main()
{
int a[2][5], i,j; //2d array declaration
for(i=0;i<=1;i++) //first loop for 1st dimension
{
for(j=0;j<=4;j++) //nested loop for 2nd dimention
{
printf("Value for a[%d][%d] is : ", i,j);
scanf("%d", &a[i][j]); //asks for value
}
}
}
In this program, when the loop is executing, in the first run, i=0, and inside that j=0,1,2,3,4.
When this is done and it comes to the 2nd dimension where i=1, why does it run the nested loop again when the condition is already false (j<=4)?
Where are all these constant values saved? Does it restart the value of j when the nested loop is run again?
A for loop has three components (expressions) in the form for (A;B;C):
A - Pre-Iteration, run once at the start
B - Loop Condition, tested before each iteration, including the first
C - Post-Iteration, executed after each iteration
You're asking to initialize j=0 each time the loop starts, then testing j <= 4 which will be true. When the loop repeats it does j++, then tests again.
It's worth noting that these are all optional and for (;;) is valid, but is an infinite loop unless you break it.
With minor improvements:
int main(void) //added int and void to main
{
int a[2][5], i,j; //2d array declaration
for(i=0;i<2;i++) //first loop for 1st dimension
{
for(j=0;j<5;j++) //nested loop for 2nd dimention
{
scanf("%d", &a[i][j]); //asks for value [note, before printf]
printf("Value for a[%d][%d] is %d\n: ", i,j, a[i][j]);
}
}
return 0;//int main(void) requires a return statement
//Note also, 'main()' is really not a proper signature for
//the main function
}
This code intends to assign values to each member of the 2D array by using prompted input values using scanf, but because of some syntax and logic errors, the original would not work as intended. To help, the order of the two lines in the nested for loops has been switched to prevent the array from being accessed before being initialized.
The nested for loop indexes have been modified in this version to use the same values for limit, as those used to size the array in its declaration:
int a[2][5];
for(i=0;i<2;i++)
for(i=0;j<5;i++)
scanf() is the method used for user input. Each call prompts for a value, which is placed into the corresponding row-column index indicated by i and j, and written to stdout. Note the actual value in the original code is not printed out, but it is in this slightly modified version.
The value of j is initialized to 0 each time you run the nested loop because you set the initialize expression of the for statement to "j=0"
That expression will be run for each execution of the outer loop

Why no output when index value is 0

Change the value of index from o to 1. loop is printing value. Why it is not printing any value when index is assigned to 0?
Currently i = 0 - No Output
Make i = 1 - infinite loop
#include<stdio.h>
int main()
{
for(int i = 0;i++;i<100)
{
printf("Mahesh\n");
}
}
enter code here
C for loop structure:
for ( init; condition; increment )
You have actually added i++ in the place of condition and i<100 in the place of increment.
Flow Control of for loop in C:
init step is executed first and only once.
Condition is evaluated next and if it is True, the body of the loop is executed. If False, the body of the loop doesn't execute and the flow jumps to the next statement after the for loop.
After the body of the loop executes once, the flow control jumps to increment statement and then condition is evaluated again.
Body of loop, Condition and increment steps are repeated in the same order till the condition becomes False after which the for loop terminates.
Your loop is:
for(int i = 0;i++;i<100)
In this, you have i++ as the condition. Now, in this i is evaluated first followed ++. Since, i is 0, it leads to the loop exiting as the condition evaluates to False. But, if you change i to 1, the condition (i.e. i) evaluates to True and it enters the loop.
If you have not done this deliberately, you need the loop like below:
for (int i = 0; i < 100; i++)
The syntax for a for loop in C is as follows:
for ( init; condition; increment ) {
statement(s);
}
-init: initialising the index variable with the value you would like to start the iteration at.
-condition: the condition for the iteration to continue until met
-incremenet: indicating how much you want the program to incremenet your index by
Hence in your example is should be:
for(int i = 0; i < 100; i++){
//yourcode
}
Hope that helps
The parameters of for loop are:
for(initialization; Condition; Next iteration initialization){
//code
}
The initialization(s) can be more than one separated by commas.
The condition will continue if have 1 (or the value TRUE which means the same thing as 1) or will break if the condition is not met i.e the value 0 (or FALSE). You can have multiple conditions as well by the use of && or || or commas.
The third parameter is what you want to do in the next iteration. It can have multiple commands too. I suggest you run the following code and change it to observe the results:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j;
for( i=0,j=0;i<10 || j<5;i++,j++)
printf("%d\t%d\n",i,j);
return 0;
}
#include<stdio.h>
int main()
{
int i = 0;
// Postfix Increment Operator
for (i = 0; i++; i<100) // Condition is false, Because the i is Zero
{
printf("Mahesh");
}
printf("%d", i); // i outputs One here
// Prefix Increment Operator
for (i = 0; ++i; i<100) // Condition is True, Because the i is One
{
printf("Mahesh");
}
}

Nested for loop saving last input not whole input

I'm back again with that C question heh. So I'm trying to get the user to input a whole 2d array (size, values, everything), with VLA arrays (im using the latest compiler). Everything is fine up until I get the nested for loop, then it saves the last value into the array and ignored anything before it. I cannot seem to figure out how to fix my VLA to iterate through every element in the array and assign the value typed in by the user, all I get is it saving my last value into the whole array. Through some testing I've found that my problem is contained in my Inner loop of my nested for loop. EDIT: Through the help of Weather Vane, it was figured out that the array needs to be initialized after my x and y are saved, but now it saves my last value in the whole array and not every value typed. Here's my code snippet:
int x, y, row, col, a = 0;
//int NxM[x][y]; Moved
bool counter[10]; //I have 1 last part to code that involves this
printf("This program counts occurrences of digits 0 through 9 in an NxM
array.\n");
printf("Enter the size of the array (Row Column): ");
scanf("%d %d", &x, &y);
int NxM[x][y]; //Moved here.
for(row = 0; row < x; row++){
printf("Enter row %d: \n", a);
a++;
for(col = 0; col < y; col++){
scanf("%d ", &NxM[x][y]);//Why you only save 1 value >.<
}
}
(The reason I have my printf statement between my loops was to test where my looping problem was, and because I need my printf to look like Enter row 0 Enter row 1 etc..)

what's the difference between these two in C?

in learning quick union algorithm, i have met these two statements
for(i=p; i!=id[i]; i=id[i]);
for(j=q; j!=id[j]; j=id[j]);
since I only learned for loop to be something like
for(i=0; i<100; i++)
I don't know the difference between the two statements and the following statements
i=p; i=id[i];
j=q; j=id[j];
i have no idea why the results are different?
thanks
I want to ask why
#include <stdio.h>
#define N 10000
int main()
{
int i, j, p, q, id[N];
for(i=0; i<N; i++) id[i]=i;
while(scanf("%d %d\n", &p, &q)==2)
{
for(i=p; i!=id[i]; i=id[i]);
for(j=q; j!=id[j]; j=id[j]);
if(i==j) continue;
id[i]=j;
printf(" %d %d\n", p, q);
}
}
is different from
#include <stdio.h>
#define N 10000
int main()
{
int i, j, p, q, id[N];
for(i=0; i<N; i++) id[i]=i;
while(scanf("%d %d\n", &p, &q)==2)
{
i=p; i=id[i];
j=q; j=id[j];
if(i==j) continue;
id[i]=j;
printf(" %d %d\n", p, q);
}
}
I have tested the results, that's why I am confused
i=p;
Sets i to the value of a variable p (defined and initialized elsewhere in the program)
i=id[i]
Sets i to the value of the i th element of the array id (defined and initialized elsewhere in the program)
for(i=p; i!=id[i]; i=id[i]);
Loop initializes i to the value of p, executes the statements inside the for loop once if i is not equal to the i'th value of the array id, and then stops.
Further explaination:
assuming some values for the variables:
int p = 4;
int i;
int id[5] = {1,2,3,4,5};
for(i=p; i!=id[i]; i=id[i]) {
printf("Loop executed!\n");
}
Output:
Loop executed!
And then a segmentation fault.
What happens:
i is set to 4, then compared to id[4]. This is unequal, thus the loop is triggered. After that it sets i to 5. Now it tries to compare id[5] to i. This is disallowed because id only has space for 5 elements and indexes start at 0.
When looking at non-standard for "loops" like this, it helps to convert your for loops into while loops. (that is all they really are)
To do that, remember that a for loops consists of three parts separated by semicolons. The initialization part, the conditional part, and the update or increment part:
for(initialize statement; boolean loop conditional; update/increment statement);
The initialize statement is executed before your loop, the loop conditional is evaluated to determine whether the loop continues, and the update/increment statement is executed as the end of the loop.
Your first example:
for(i=p; i!=id[i]; i=id[i]);
As a while loop, looks like..
i = p
while(i!=id[i]) {
i = id[i];
}
Your second example:
for(j=q; j!=id[j]; j=id[j]);
As a while loop, looks like..
j = q
while(j!=id[j]) {
j = id[j];
}
Once they're written like this, it's easier to tell what's going on.
We're initializing the loop variable to one of two values, p or q.
Then, we're looking into the array "id" at the location specified by the loop variable and updating the loop variable with it. This has the effect of looking up in the array the next loop variable. In other words, each slot in the array contains the next value to jump to.
The conditional checks to see whether the destination is the same as the current location. That is to say, if we are "told" to jump to the location we're already in.
The difference between you two loops is only the initialization value. The first one initializes to p where the second initializes to q.
It may be helpful to manually jump through a simple cases such as..
p=0
q=1
id = {1,2,2}
p=2
q=1
id = {0,0,2}

If same count variable 'i' is treated as different in each nested for loop,then why is change to it in inner loops sustained outside?

Apropos the question "Why does using the same count variable name in nested FOR loops work?" already posted in this forum,a count variable "i" defined in each nested loop should be considered a new variable whose scope is limited to that loop only.And we should expect that variable's value to be erased and overridden by the value of "i" which was in the outer loop (before control passed to inner loop).But in my following code, when the control comes out of the inner loop,instead of the variable "i" having the value 0 (which was it's value in the first iteration of outer loop,before control passed to inner loop),it continues to have the value 10 instead (which it got in last iteration of inner loop).Then this 10 is incremented to 11 and hence the condition of the outer loop in not satisfied and the outer loop exits.
I had expected my program to print the numbers 0 to 9 horizontally 10 times, in 10 different lines.But it prints just for one line and exits.
And here's another thing to it--If I use any number greater than 10 in the outer loop condition (i<=10),then it creates an infinite loop.According to my reasoning, it happens because i gets a value of 11 after the first iteration of outer loop and hence if condition is <=11 or more then the outer loop comes to another iteration.Whereupon i is again initialized to 0 in inner loop and the cycle continues.
Sorry if I couldn't put my question very clearly.All I want to ask is, isn't the inner i supposed to be a different variable if we are to assume the linked question on this forum is correct?Why then the value of i continues to hold on after we exit inner loop,instead of reverting to the value of i that was there when we entered the inner loop?
#include <stdio.h>
int main()
{
int i;
//for (i = 0; i <= 11; i++) Creates infinite loop if this condition is used instead
for (i = 0; i <= 9; i++)
{
for (i = 0; i <= 9; i++)
{
printf("%d ", i);
}
printf("\n");
}
}
OUTPUT : 0 1 2 3 4 5 6 7 8 9
PS: As a secondary question, is it impossible to print the number 0 to 9 horizontally, in 10 different lines, using nested for loop if we use the same count variable in each loop,as I have done here? (Ignore this secondary question if it's not relevant to main question)
The answer you linked to is using different variables with the same name, you're simply using the same variable.
Compare:
for(int i = 0; ...
to:
for(i = 0; ...
The former declares a new variable called i, which is how you nest loops like the linked-to answer. Not that I would ever (ever!) recommend doing so.
As you've noticed, support for the former syntax wasn't added to C until C99.
If i were defined in each loop then the behaviour would be as your linked question. In your example you only define i once, outside any loop, then reuse it
int i;
for(i=0; i<=9; i++)
{
for(i=0; i<=9; i++)
{
is not the same as
for(int i=0; i<=9; i++)
{
for(int i=0; i<=9; i++)
{
If you want each for loop to have its own i, you need to create i individually for each. As-is, you have exactly one i that's defined outside both loops, so the modifications done by one loop affect the value seen by the other.
int i;
for (i=0; i<10; i++) {
int i; /* define another i for the inner loop */
for (i=0; i<10; i++)
printf("%d\t", i);
printf("\n");
}
Note that I'd generally recommend against this -- while the compiler has no problem at all with having two variables with the same name at different scopes, code like this where it's not immediately obvious what i is being referred to when may well confuse people reading the code.
All I want to ask is, isn't the inner i supposed to be a different
variable
no, there is only one declaration, so only one variable
Sorry - late response, but couldn't help but notice:
The reason it "works" is that the inner loop resets i to zero, prints & increments i, and returns to the outer loop - at which point i>9 so the outer loop exits.
There is only one iteration of the outer loop and the values printed are entirely determined by the inner loop. It's not a question of scope, it's the fact you reassign new values to i in the inner loop.
PS: As a secondary question, is it impossible to print the number 0 to 9 horizontally, in 10 different lines, using nested for loop if we use the same count variable in each loop, as I have done here? (Ignore this secondary question if it's not relevant to main question)
Of course you can, but you need a more complex format string for your printf.
printf("%d ",i);
The above statement works by printing I, immediately followed by a space, and leaving the carriage where the print stops.
The effect that I think you have in mind is something like the following.
0
1
2
3
4
5
6
7
8
9
To make that happen, you need a couple of changes to your printf statement, as illustrated in the following complete program.
// MarchingDigits.cpp : Defines the entry point for the console application.
//
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
for ( int i = 0 ; i < 10 ; i++ )
{
printf ( "%*d\n", ( i > 0 ? i + 1 : i ) , i ) ;
} // for ( int i = 0 ; i < 10 ; i++ )
return 0;
} // int main
The output generated by this program is as follows.
0
1
2
3
4
5
6
7
8
9
There are three fundamental differences between your printf statement and the one that generated this output.
Between the opening % and the closing d, I inserted an asterisk where the width goes.
I replaced the trailing space with a newline.
Between the format string and your integer argument i, I inserted another argument, in the form of a ternary expression, i > 0 ? i + 1 : i, which says, in effect, if I is greater than zero, set the width to i + 1, otherwise set the width to i. Although the else block sets the width to i, which happens to be zero, this works because printf guarantees never to truncate the output.

Resources