Nested Loop Unexpected Behavior - c

I'm trying to debug my program with a nested loop to print out all the values in a 2d array. I was getting some unexpected behavior from the loop so i commented out some things and added a simple printf.
`int u = 0;
int y = 0;
char m = 'm';
for (u; u < 12; u++)
{
printf("\n");
for (y; y < 5; y++)
{
//transition[u][x] = &m;
printf("o"); //this nested loop isnt working????
//printf("%c", *transition[u][y]);
}
}`
Clearly this should print 12 rows of 5 'o's. But instead it is only printing out one row of 5 'o's followed by 11 newlines.
Edit: Thanks a lot! Silly mistake, I failed to realize that y would not set itself back to 0 on the second run through the loop. I guess overlooked this because I'm too used to Java initializing and setting the increment variable within the loop statement.

Your for initial statement doesn't mean anything:
for (y; y < 12; y++)
The first statement is just y. Which has no side effects so you are not actually resetting y to 0 after first innermost loop. So from next iteration of outer loop, y == 5 and the inner loop is not executed at all.
You should do
for (y = 0; y < 12; y++)

You are not resetting y on your inner loop; try for (y = 0; y < 5; y++).
This will reset y at the beginning of each loop.
p.s. This is really more of a code review question

By looking at your question i assume that you are trying to print 5 o's in a line with 12 o's.
try this
for(u=0;u<12;u++)
{
for(y=0;y<5;y++)
{
printf("o");
}
printf("\n");
}

Related

C: For Loop: Why does a loop-continuation condition of "z" work the same as "z > 0"with a decrement of z--?

Full disclosure: I think I have answered my own question by formalising all of this. Please can you check my logic?
Using the following terminology:
for (initialise control variable; loop-continuation condition [Boolean expression]; de/increment)
I have written a loop which prints out a Mario style pyramid:
Welcome to Super Mega Mario!
Height: 5
# #
## ##
### ###
#### ####
##### #####
Within the code, I use two different loop-continuation conditions:
for (int z = i + 1; z > 0 ; z--)
for (int z = i + 1; z ; z--)
I am unsure why the second example works, below is my attempt to explain.
Why I think both of these work:
First example (z > 0):
To print the final line ##### #####, the for function prints "#" 5 times. First, because z == 5, so Bool is true, so print "#". Then z == 4, Bool is true, so print "#". This continues
until z == 0, so the Bool is FALSE, so break.
Second example (z):
All non-zero values are true, z is 5,4,3,2,1. When z is 0 (FALSE), break.
I am learning, I want to develop excellent style and design, if you can explain which example is better designed, please let me know! Also, if you can recommend edits for my style, then please HMU too. [Source code # end].
int main(void)
{
int n;//Declare variables outside of loops to allow "while" function to use it.
printf("Welcome to Super Mega Mario! \n");
do
{
n = get_int("Height: "); //prompt user for height of pyramid.
}
while (n < 1 || n > 8);
for (int i = 0; i < n; i++)//How many rows will be created
{
for (int j = 0; j < n; j++) //column
{
for (int x = n - i - 1; x; x--) //for(initialise control variable; loop continuation condition [boolean expression]; increment)
{
printf(" ");
}
for (int y = i + 1; y; y--) //If the loop continuation condition is y, then it's TRUE. So the function will run. Then it decreases this value by 1, so it's now 0 or FALSE so the function breaks.
{
printf("#");
}
printf(" ");
for (int z = i + 1; z > 0 ; z--) //In theory "z>0" works the same as z on its own.
{
printf("#");
}
break;
}
printf("\n");
}
}
z inside an expression is equivalent to z != 0. All non-zero values (positive or negative) are to be regarded as a boolean true when placed inside an expression. Similarly, given a pointer int* p; then if(p) is equivalent to if(p != NULL).
if you can explain which example is better designed, please let me know!
Style is subjective, though generally it is regarded as better style to be explicit, since that gives self-documenting code and rules out typos. If I type if(p != NULL) then there can be no misunderstanding what I meant the code to do. If I however type if(p), that could either be what I meant, or it could potentially be a bug when I actually meant to de-reference the pointer if(*p).
On the topic of style, it is often best to keep for loops as simple as possible. That means avoid needless complex expressions in the 3 for clauses and do up-counting loops whenever possible. The idiomatic form of a for loop is:
for(int i=0; i<n; i++)
and we should try to strive to be as close to that as possible. For example in case of for (int z = i + 1; z > 0 ; z--) it doesn't matter which order you iterate in, so the down-counting is just obfuscation. There is no reason why this shouldn't be written as for(int z=0; z<i; z++).
Also style: no matter which brace placement style you use, it is convention to always write the while in do while at the same line as the }. That is: } while (n < 1 || n > 8);
Bug here: break; prevents the for (int j = 0; j < n; j++) loop from running more than once.

variables 'y' and 'x' used in loop condition not modified in loop body - help, previous answers have not helped

Please could someone help with this - I am completely new to coding and just started the cs50 course, I really am struggling to understand most of the course. I've scraped through this lab but I keep getting this error message "population.c:22:17: error: variables 'y' and 'x' used in loop condition not modified in loop body [-Werror,-Wfor-loop-analysis]
for (n = 0; y < x; n++)". I've tried to look through similar questions on here and apply those solutions, none of which have worked. Could someone please help?
My code is below
#include <cs50.h>
#include <stdio.h>
int main(void)
{
// TODO: Prompt for start size
int x,y,n ;
do
{
x = get_int("Start size: ");
}
while ( x < 9);
// TODO: Prompt for end size
do
{
y = get_int("end size: ");
}
while (y < x);
// TODO: Calculate number of years until we reach threshold
for (n = 0; y < x; n++)
{
n = x + x/3 - x/4;
}
printf("Years: %i", n);
// TODO: Print number of years
}
for (n = 0; y < x; n++)
{
n = x + x/3 - x/4;
}
This loop keeps executing while y is less than x. However, the only variable that changes inside the loop is n. x and y remain unchanged.
So either this loop will never run, or it will run forever.
It would really help to know what the goal of the exercise is.
What we know from what you’ve posted is that the initial value of x must be greater than or equal to 9 and that the initial value of y must be greater than or equal to x.
Based on that alone, we know your loop will never execute since y < x will not be true. Based on the calculation involving x and the comment about reaching a threshold, I strongly suspect your loop is supposed to be written as
for ( n = 0; x < y; n++ )
{
x = x + x/3 - x/4;
}

C looping counting up

I'm a beginner at C and can't find the answer to this anywhere because I don't know how to word it so I'm just going to ask a question.
I understand basic looping but what I want to do is make a small program where the output is this using only loops:
12345
1234
123
12
1
my code so far
int x;
int y = 1;
for (x=1; x<=5; x++)
{
while(y<=5)
{
printf("%d", y);
y++;
}
}
this is what I have so far and don't know where to go next, if anyone could help I'd be grateful.
Close. Your outer loop needs to count down, not up, and your inner loop needs to count from 1 to x.
int x, y;
for (x=5; x>=1; x--)
{
for (y=1;y<=x;y++)
{
printf("%d", y);
}
printf("\n");
}
This is another solution using just a FOR loop with Integer Division. Try:
#include <stdio.h>
int main(void){
int n= 12345, i;
for(i=n;i>0;i/=10){
printf("%d\n",i);
}
return 0;
}
You have to see the pattern you want and apply it in the loops to get it.
You need the output 12345 1234 123 12 1. So, the first iteration should start at 1 and go till 5, second should start at 1 and go till 4, and so on..
So, the outer loop should give the end limits for the inner loop, and the inner one should always start with 1.
Try
for (x=5; x>=1; x--)
{
y = 1; // because the number always start with 1
while(y<=x)
{
printf("%d", y);
y++;
}
printf("\n"); //to go to next line
}
For fun: another approach that simply divides each loop. But use best answer
int main(void) {
int x = 12345;
do {
printf("%d\n", x);
x /= 10;
} while (x);
return 0;
}
Output
12345
1234
123
12
1
Another solution is to use integer division and use one single loop:
int x = 12345;
// repeat this loop as long as x != 0
while (x)
{
printf("%d\n", x);
x /= 10; // x = x/10;
}
You need to make 2 changes to your outer loop in order to get the expected output.
for (x=1; x<=5; x++) should be for (x=1; x<=5; x--) because your program will count up to 5 the first time, 4 the second time, 3 the third time, etc..
You should include printf("\n") so a new line is printed after each sequence is output.
You need to make 1 change to your inner loop as well:
Instead of y <= 5 you should say y <= x because x will always be equal to the last number that you want to print since you're decrementing it in the outer loop.

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.

C arrays and loops

I'm new to C and I got an assigment from school to calculate some stuff, but when I run the program nothing shows up, can anyone figure out what's wrong with this?
#include <stdio.h>
void main()
{
int arr[]= {3,6,18,12,15,30,60,70,11,10};
int rt,i,x;
for (i = 0;i >= 10; i++)
rt += arr[i];
for (x = 0;x >= 10; x++)
{
printf("The value of resistor at location %d is %d\n",i,arr[i]);
printf("The value of the RT is %d\n",rt);
}
}
Your for loop conditions to exit the loop are wrong. Specifically, i should be < 10 not >= 10. When i = 0, the loop immediately terminates because it isn't >= 10. As such, you need to modify your code so that it's < 10. The reason why is because C starts at index 0 when referencing an array, and you have 10 elements in your array. Also, rt looks like an accumulator variable, and so you'll also need to set this to 0 before looping.
Another small but fundamental bug in your code is the second for loop. Specifically, your increment variable is x, but you are using i within the for loop. As such, either change the variables within the for loop to x, or change the loop index so that it is i and not x. I did the former.
Another small suggestion I have is to place the printf statement that displays the rt variable outside of the for loop. This variable never changes during each iteration, and so it is safe to assume that you only want to display it once.
As such:
#include <stdio.h>
void main()
{
int arr[]= {3,6,18,12,15,30,60,70,11,10};
int rt,i,x;
rt = 0; // As you are accumulating values
for (i = 0; i < 10; i++)
rt += arr[i];
for (x = 0; x < 10; x++)
printf("The value of resistor at location %d is %d\n",x,arr[x]);
printf("The value of the RT is %d\n",rt);
}
The statement
for (x = 0;x >= 10; x++)
should be
for (x = 0;x < 10; x++)
otherwise it will never execute since first x is assigned zero, then you check if x >= 10.
Right off the bat? Your for loop condition is not correct, it's backwards.
for (i = 0;i >= 10; i++)
should be:
for (i = 0;i < 10; i++)
Your for loop should be testing x<= 10.

Resources