Reputation:
So I am working with For Loops as part of my school and I have some code that works but I am struggling to understand why it works. It is important for me to really understand why a block of code does what it does - not just that it works.
So a little bit of background. This mini-program utilizes the for loop in order to print a series of #
characters depending on user input. The idea is that a user enters a number between 1 and 8, and the program will print a #
character, then move to the next line and print another two, move to the next line and print three etc. and print as many lines as the user inputs.
Input: 5
Output:
#
##
###
####
#####
The program is here:
#include <stdio.h>
int main(void) {
int rows = 1, height, hash = 1;
printf("Enter a number between 1-8: ");
scanf("%i", &height);
if (height >= 1 || height <= 8) {
for (rows; rows <= height; rows++) {
for (hash; hash <= rows; hash++) {
printf("#");
}
printf("\n");
}
}
return 0;
}
I have written the loop down and tried to understand it as follows. If someone could clarify that I have the understanding of how these nested loops are working it would be appreciated:
So here is my main question: I'm struggling to see how and why the program is able to print more than one #
using the printf statement when it goes down to a new line. I believe the printf statement is printing two #
characters due to the rows
variable contained in the nested for loop.
I am assuming this as when I change the code in the nested for loop to for (hash; hash == rows; hash++)
then only one #
character is printed for each line. Same as if I change the code to for (hash; hash <= rows + 1; hash++)
it will add a #
character to each line.
Some clarification would be appreciated and help with my school work. I thank you all in advance!
Upvotes: 0
Views: 596
Reputation: 311088
Variables should be declared in the place where they are used.
It is a reason of various errors when between a variable declaration and its usage there are much code.
The variables rows
and hash
are used only within loops. So they should be declared in these loops. In this case you could avoid the error relative to forgetting to reinitialize the variable hash
within the inner loop.
If you supposing that the values of a variable should not be negative then declare the variable as having unsigned integer type instead of a signed integer type.
It is unclear why in your program there is used magic number 8
. Why can not the height of the figure be greater than 8?
The program can look the following way.
#include <stdio.h>
int main(void)
{
while ( 1 )
{
const char c = '#';
unsigned int height;
printf( "Enter the height of a pyramid (0 - exit): " );
if ( scanf( "%u", &height ) != 1 || height == 0 ) break;
putchar( '\n' );
for ( unsigned int i = 0; i < height; i++ )
{
for ( unsigned int j = 0; j < i + 1; j++ )
{
putchar( c );
}
putchar( '\n' );
}
putchar( '\n' );
}
return 0;
}
Its output might look like
Enter the height of a pyramid (0 - exit): 1
#
Enter the height of a pyramid (0 - exit): 2
#
##
Enter the height of a pyramid (0 - exit): 3
#
##
###
Enter the height of a pyramid (0 - exit): 4
#
##
###
####
Enter the height of a pyramid (0 - exit): 5
#
##
###
####
#####
Enter the height of a pyramid (0 - exit): 6
#
##
###
####
#####
######
Enter the height of a pyramid (0 - exit): 7
#
##
###
####
#####
######
#######
Enter the height of a pyramid (0 - exit): 8
#
##
###
####
#####
######
#######
########
Enter the height of a pyramid (0 - exit): 9
#
##
###
####
#####
######
#######
########
#########
Enter the height of a pyramid (0 - exit): 10
#
##
###
####
#####
######
#######
########
#########
##########
Enter the height of a pyramid (0 - exit): 0
Now let's consider how the program works.
The outer loop
while ( 1 )
{
//...
}
is an infinite loop because its condition is never can be equal to 0.
The loop is interrupted when either the user entered an invalid data or when he entered 0.
if ( scanf( "%u", &height ) != 1 || height == 0 ) break;
Now all is ready to output the pyramid.
This loop
for ( unsigned int i = 0; i < height; i++ )
{
//...
putchar( '\n' );
}
in fact is line manager. Try the program by commenting the inner loop and you will see that blank lines will be outputted number of which corresponds to the value of i + 1
The inner loop outputs the number of the symbol '#' that corresponds to the value of the expression i + 1
. That is when i is equal to 0 one symbol '#' is outputted. When i = 1 when two (i + 1) symbols '#'
are outputted and so on.
So the inner loop outputs a line of i + 1
symbols '#'
and the outer loop goes to the next line..
Upvotes: 2
Reputation: 9173
Your problem is hash
variable. It does not reset to 1
when your inner for
loop starts again.
Here is correct code:
int main(void) {
int rows = 1, height, hash = 1;
printf("Enter a number between 1-8: ");
scanf("%i", &height);
if (height >= 1 || height <= 8) {
for (rows; rows <= height; rows++) {
for (hash = 1; hash <= rows; hash++) {
printf("#");
}
printf("\n");
}
}
return 0;
}
In your code scope of hash
is outside of both loops, so in next runs of inner for
loop, you practically start it with hash
equal to 2
, 3
, 4
, 5
.
You have set hash=1;
at start of your code which sets it to 1
when program starts. But you have never reset your hash
variable after inner loop finishes.
Here is how values change in your code:
iteration row hash
--------------------------------
1 1 1 -> #
1 2 -> inner loop end
2 2 2 -> #
2 3 -> inner loop end
3 3 3 -> #
3 4 -> inner loop end
4 4 4 -> #
4 5 -> inner loop end
5 5 5 -> #
5 6 -> inner loop end
6 6 6 -> outer loop end
Upvotes: 4
Reputation: 63
The first loop is for the rows and the second loop is for the number of the # s inside the rows.
When you execute (hash; hash == rows; hash++)
condition hash==rows
is only correct once. for
loop keeps increasing the hash
value when the value of hash
and rows
is equal, it executes the code block.
The second one (hash; hash <= rows + 1; hash++)
.
Let's trace it. First iteration :
hash
is 1,
rows
is 1,
(1;1<=1+1;hash++)
this loop will execute twice, first one because of 1<=1+1
and the second one because of 2<=1+1
Upvotes: 0
Reputation: 582
the first argument "rows" in the statement means that you are iterating the rows integer. second statement "rows <= height" means : keep incrementing rows as long as rows less than or equal to height" so when rows is equal to 5, the loop will finish.
For the furst loop, it iterates 5 times as follows:
rows = 1
rows = 2
rows = 3
rows = 4
rows = 5
the second loop prints hashes according to the number of rows. When riws is 1, only one hash is printed. And after each loop, a new line is printed.
Upvotes: 0