Logic of for loop in C - c

****
***
**
*
/*code for this pattern*/
#include<stdio.h>
int main()
{
int i, j;
for (i = 4 ; i >= 1 ; --i) {
for (j = 1 ; j <= i; ++j) { /*why does j<=i?*/
printf("*");
}
printf("\n");
}
}
So why does j <= i? the first for loop is responsible for the rows. While the second for loop in responsible for the number of stars in each row. again, i don't understand the logic of the condition- j <= i.
EDIT: C is the first language I have ever tried to really learn. The question is pretty clear, i think. I don't understand the condition component of the for loop. Thats all. Some people understood what I was asking though. thanks
EDIT2: seems like i wasn't clear with my question. I want to to know why does j has to be less or equal to i. why can i be less or equal than j? I am having trouble seeing the relationship between i, the number of rows and j, the number of stars in each row.
Thanks

As you said, the outer for loop is for the number of rows. The inner for loop is to print the * n times, where n is the number of times the character has to be printed in that row.
i.e) In the first iteration : i = 4, so, j = 1;j<=4 executes 4 times so you print 4 *.
In the second iteration : i = 3, so j = 1;j<=3 executes thrice, so you print 3 *

i starts high and decrements while i is >= 1. j starts low at 1, and increments while j is <= i.
This means that while i is a greater value, j will be incremented more times, which means we want to start off with printing a greater amount of ''s from the start, and after each newline character, slowly narrow that strand of ''s.
The inner loop is essentially there to execute that printf() call exactly i times. So you end up with 4 '*'s for the first iteration, 3 for the next, 2, then 1. Each on a new line.

The number of stars on each row, and the number of rows remaining to print (including the current row) are both equal to i. So i is being used both to countdown the number of rows left to print, and also as the number of stars to print on each row. On the first row i == 4, so you want to print four stars, so you have a loop:
for(j = 1; j<=4; ++j) {
printf("*")
}
next time i will be 3, so the inner loop will be:
for(j = 1; j<=3; ++j) {
printf("*")
}
and so on.

You asked:
for(j = 1; j<=i; ++j){ /*why does j<=i?*/
When i is equal to 4, you want to print four *s.
When i is equal to 3, you want to print three *s.
The check j <= i makes sure of that.

For each loop, you should think about how many times it is iterated.
As you said, in the first for loop,
for(i = 4; i >=1; --i){ ...
This for loop iterates while i >= 1, meaning i changes to 4 -> 3 -> 2 -> 1 (i.e. 4 times = number of rows).
For each row, you want to print i number of *'s, which means you want to repeat the printing process i times for each row. In the nested loop,
for(j = 1; j <= i; ++j){ ...
j iterates while j <= i, meaning 1 -> 2 -> ... -> i (i.e. i times for each row). It is by the way practically the same as
for(j = 0; j < i; ++j) {...
which iterates i times as well.

Related

Print number pattern with a single for loop without an if statements

I need to print the following pattern using a single for-loop without if statements.
1
21
321
I first tried to understand the logic and coded it using 2 for loops:
for (int i = 0 ; i <= num; i++) {
int temp = i;
for (int j = 0; j < i; j++){
printf("%d", temp);
temp--;
}
printf("\n");
}
However, I have no clue on how to approach this without a for loop AND no if statements.
Any hints/tips would be greatly appreciated.
Make a loop that will print integer 321 three times.
Modify loop print statement to print remainder of 321 divided by 10. Each line will now print 1.
After print statement, multiply divider by 10, so that after each loop iteration divider is 10 times bigger.
You can store the previous line and use it to produce new one. Here's naive implementation, working for up to 9 lines.
int main()
{
int num = 3;
char buffer[100] = {0};
char temp_buffer[200] = {0};
for (int i = 1 ; i <= num; i++) {
sprintf(temp_buffer, "%d%s", i, buffer);
printf("%s\n", temp_buffer);
strcpy(buffer, temp_buffer);
}
return 0;
}
Try to write loops as close to the most trivial/canonical form as possible:
for(int i=0; i<n; i++)
That means: avoid iterating starting from 1, avoid comparing with <=, avoid down-counting loops. There's a place for all of these things but avoid them when you can for the sake of readability and keeping things simple. As a bonus, readable loops are very often also fast loops.
In this case 2 for loops isn't a bad idea. You can consider the output a matrix of sorts, then have an outer for loop for "rows" and the inner one for "columns".
Write the outer for loop in the canonical form I showed above where n would be your maximum, such as 3.
Write the inner for loop so that it iterates from zero up to "rows" - the outer loop iterator. However, you don't want to write 0, 10 and so on so you should also compensate for this by adding + 1. So the upper limit condition of the inner loop could be cols < (rows+1).
Then when printing in the inner loop (assuming you took my advise to make it up-counting), print descending by starting at your max value rows+1 then subtract the current value. That is (rows+1) - cols.
Change new line in the outer loop, after printing each row, like you are already doing.
Result:
#include <stdio.h>
#define MAX 5
int main (void)
{
for(int rows=0; rows<MAX; rows++)
{
for(int cols=0; cols<(rows+1); cols++)
printf("%d",(rows+1)-cols);
printf("\n");
}
}

Understanding two dimensional arrays

Here's the code and wondering if you can help me understand it.
/* Two dimensional array */
#include <stdio.h>
void main() {
int i, j, sum[2], mean[2];
int mark[3][2] = { { 34, 56}, { 48, 65}, { 53, 59} };
for (j = 0; j < 2; j++)
sum[j] = 0;
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
sum[j] = sum[j] + mark[i][j];
}
}
for (j = 0; j < 2; j++)
mean[j] = sum[j] / 3;
printf("Average mark in Mathematics is %d\n", mean[0]);
printf("Average mark in Chemistry is %d\n", mean[1]);
}
My understanding of it so far....
Define data types i, j, sum[2], mean[2] as integers.
Initialising the array....mark is data type int, the array should have 3 rows and 2 columns.
First for loop, j initialised at 0, condition: j has to be less than 2, update: add one onto the value of j. Sum of j = 0.
Also for 2nd loop, i initialised at 0, condition: i has to be less than 3, update: add one onto the value of i.
Similar for the next line that uses the for loop and value j.
I'm a bit confused about the syntax:
sum[j] = sum[j] + mark[i] [j]; does this mean, work out the sum of j and add it to the marks contained in the array displayed as [i] and [j].
After this is completed then similar j loop though not sure how this interacts with the previous loops.
Mean calculated and values printed to the screen.
When I've looked at the worked example...
sum[0] = 0 and sum[1] = 0, I don't really understand why sum[1] is also 0.
Firstly, i=0 and j=0,
sum[0] = sum[0] + mark [0,0]
then j=1
sum[1]=sum[1]+mark[0,1]
then
i=1, j=0
sum[0] = sum[0] + mark [1,0]
then
sum[1] = sum[1]+mark[1,1]
then i = 2, j=0
sum [0] = sum[0]+ mark[2,0]
then
sum[1] = sum[1]+ mark[2,1]
What is confusing me a bit is how the loops are interacting with each other and the values of i and j throughout.
I know that the 2d array would be in a table (that I can't seem to format here).
Would appreciate if anyone could shed some light on this.
sum[j] = sum[j] + mark[i][j]; can be simplified as sum[j] += mark[i][j];. It adds the contents of the cell at row i, column j of the 2D matrix mark to the jth element of array sum.
Accessing an element of a 2D array is written mark[i][j] in C, not mark[i, j].
Note that mark[i, j] is not a syntax error: the expression i, j is a comma expression, evaluating i, then discarding it and evaluating j. It is therefore the same as mark[j] which is not a matrix cell but a reference to the jth row of the 2D matrix.
Nope, an array is in fact a pointer (aka an address). When you define int sum[2], sum is the address of the first element of your array of two integer.
So sum is an int* or int[] (same).
Mark is an 2d array. Mark is in fact an array of array. So Mark contain addresses, and thoses addresses are the beggining of some arrays.
(In fact it can be different in the memory, but the compiler do the work).
Mark is a int**, or an address of address of int.
When you do:
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
sum[j] = sum[j] + mark[i][j];
}
}
It's like if you were saying
for each line i in the array, I want to do:
for each value j in the line, I want to do:
...;
Like this, you work on every "line" (or column, visualize the way you want), and for every "line", you work on every value.

print 2 numbers and skip 2 numbers in an array in C

I'm having a bit of difficulty trying to figure out a way to print some numbers in an array. I have an array[0,1,2,3,4,5,6] and I would like print the numbers 0,1,4,5. Is it possible to create a loop that can read the first two numbers skipping the next two and reading the following two numbers.
You can simply use modulo operation on current index to check if this number belongs to "print 2" or "skip 2":
int a[17];
int length = sizeof(a) / sizeof(a[0]);
for (int i = 0; i < length; i++)
{
if (i % 4 < 2)
printf("%d ", a[i]);
}
So, for i equal to 0 and 1, it will output value. For i == 2 and i == 3, the condition will result to false. Next, it will take 4, 4 % 4 is 0, and it will repeat it every 4 steps.
Pseudocode:
arr = [0,1,2,3,4,5,6];
skip = 2;
print = true;
while(i < arr.length){
for(j = 0; j < skip; ++j){
if(print){
output arr[i];
}
//increment array counter
i++;
//toggle print bool
print = !print
}
}
Just change the value of skip to set the interval, and set print = false if you'd like it to skip the first skip entries

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.

Simple nested for loops not working correctly in C (2D array initialization)

I can't understand why this simple code has this strange behaviour.
` code:
int main(){
int m[10][10];
int i=0;
int j=0;
for (i;i<10;i++) {
for (j;j<10;j++) {
m[i][j]=i+j;
printf("%d ", m[i][j]);
}
printf("\n");
}
printf("%d ", m[4][3]);
}
`
I'm expecting a matrix-like output, but the output is this:
0 1 2 3 4 5 6 7 8 9
32678
Note that the program prints 9 empty lines before 32678 (the printed value of m[4][3], obviously it should be 7). Thanks for your time.
for (i;i<10;i++)
{
for (j;j<10;j++)
In these both loops initialize iand j to 0. And you will get matrix like output.See working program here -https://ideone.com/cm3vV9
Declare like this
for (i=0;i<10;i++)
{
for (j=0;j<10;j++)
You get 9 lines between values because printf("\n"); run 9 time inside loop and then value of m[4][3] is printed (which is ofcourse not its value it throws just some random value ).
The reason m[4][3] is printing 32678 is because that portion of the array had not yet been initialized when you called printf() during the first iteration of the outer loop.
The inner loop code is ending after one iteration because you never initialize the loop counter j to 0 after each iteration of i. Use this code instead:
int main() {
int m[10][10];
for (int i=0; i<10; i++) {
for (int j=0; j<10; j++) {
m[i][j] = i + j;
printf("%d ", m[i][j]);
}
printf("\n");
}
}
Consider for (j;j<10;j++) carefully: j is not reset to zero on a subsequent iteration of i. Remedy this with for (int j = 0, j < 10, ++j) etc. and similarly for i. Drop the wider scope declarations of i and j.
The declaration inside a for loop construct has been part of C for a while now; keeping variable scope as local as possible helps program stability.
Your for loops are a bit strange, in that you aren't actually assigning anything to your loop counters in your initialization expressions. For example, this:
for (i;i<10;i++) {
is unusual... I'd expect to see this instead:
for (i = 0; i < 10; i++) {
...where i is set to 0 at the start of the loop.
For your outer loop, that quirk is harmless since you initialize i to 0 earlier in main()... but for your inner loop, it means that j does not start over at 0 for the second or subsequent times the loop is run, making the test expression false right away, and preventing the loop from running at all after the first iteration of the outer loop. That leaves most of your array (everything after the first row) uninitialized.
Changing the inner loop's initialization expression as follows:
for (j = 0; j < 10; j++) {
should fix it.
Note that eg. j; instead of j = 0; as the initialization expression is still valid, it just doesn't do anything.

Resources