Reputation:
Please explain to me how to make the program do the reseting of col
every time it went thru the loop to increase col
.
i would like to print an X amount of rows
and cols
controlled by the LENGTH
.
the code is obviously a huge mess, and i had to kind of unroll the loop. my question is how to loop correctly there actually???
it seemed very simple actually but i really couldn't wrap my head around it. for the moment, all i want to do is get the output to something like the following;
|----------------------------------------------------------------
| row: 0, col: 0| row: 0, col: 1| row: 0, col: 2| row: 0, col: 3|
|----------------------------------------------------------------
| row: 1, col: 0| row: 1, col: 1| row: 1, col: 2| row: 1, col: 3|
|----------------------------------------------------------------
| row: 2, col: 0| row: 2, col: 1| row: 2, col: 2| row: 2, col: 3|
|----------------------------------------------------------------
| row: 3, col: 0| row: 3, col: 1| row: 3, col: 2| row: 3, col: 3|
|----------------------------------------------------------------
it prints it out "all fine" (more or less) so far, but it's so stupid how i wrote that, obviously... yeah, sorry for coding like a recluse, and thanks everybody for taking your time! i'm absolutely sure you know how to do a lot better, and can perhaps explain what i'm missing here.
cheers!
float LENGTH = 0.0f;
int row = 0;
int col =0;
int main(int argc, char** argv)
{
LENGTH = 8.0f;
row = 0;
col =0;
for (;row < LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
for (;row < LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
row = 1;
col = 0;
for (;row < LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
row = 2;
col = 0;
for (;row < LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
row = 3;
col = 0;
for (;row < LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
row = 4;
col = 0;
for (;row < GRID_LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
row = 5;
col = 0;
for (;row < LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
row = 6;
col = 0;
for (;row < LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
row = 7;
col = 0;
for (;row < LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
row = 8;
col = 0;
for (;row <= LENGTH; row++)
{
for (;col <= LENGTH; col++)
{
printf("| r:%4i , c:%4i ", row, col);
}
}
printf("\n");
}
}
printf("\n");
return 0;
}
the c89 tag is there, because the program needs to run in that configuration.
the reason for that is, my plan is to dynamically allocate a number of vectors. and for that i don't want to use variable-length-arrays.
let's imagine we want to create a grid like a checker board or chess board or something of that nature. the grid should be centered in the world (x=0, y=0, z=0).
so, if the grid would be only of LENGTH = 1
then we still need 4 vectors to draw 4 lines, to get a quad at least...
but, if the user of the function calls it with
LENGTH = 1
,
then we need to add 1 to each length
(length +1)
so that when the user calls it with LENGTH = 1
we get actually at least 2x2 vectors out of it.
in the code below i'm not sure if vector
should be named vector_array
for example, since i allocate all the vectors i want.
size_t count = (((length +1) * (length +1)));
float *vector;
vector = NULL;
vector = calloc(count, sizeof(float) * 3);
my question there is, how to allocate the array of vectors, with the positions we get out of the loop so that row
and col
are both initialized like following row = -length
and col = -length
please ignore, and forgive me, that i used LENGTH
and length
interchangeably.. they mean the same all in all but LENGTH
should be used to initialize it to 1 perhaps...
size_t LENGTH = 0;
int main(int argc, const char * argv[])
{
LENGTH = 8;
float *vector;
vector = NULL;
vector = calloc(3, sizeof(vector));
if (vector == NULL)
{
printf("allocation of vector failed!\n");
exit(0);
}
float **vector_array;
vector_array = NULL;
vector_array = calloc( ((LENGTH+1) * (LENGTH+1)), sizeof(vector));
if (vector_array == NULL)
{
printf("allocation of vector array failed!\n");
exit(0);
}
int row = 0;
int col = 0;
row = (int)-LENGTH;
col = (int)-LENGTH;
while (row < (int)LENGTH)
{
while (col < (int)LENGTH)
{
vector_array[row] = row;
vector_array[col] = col;
col++;
}
row++;
}
row = (int)-LENGTH;
col = (int)-LENGTH;
while (row <= (int)LENGTH)
{
while (col <= (int)LENGTH)
{
printf("c:%d\n", vector_array[col]);
col++;
}
printf("r:%d\n", vector_array[row]);
row++;
}
return 0;
}
i can't explain it better what i try to do. i'm a beginner and i do C as a hobby...
thank you very much!
Upvotes: 1
Views: 4922
Reputation: 24921
Your loop is nested to four levels. This is unnecessary. You should only need two levels of nesting. Every iteration of the outer loop should deal with one row, and every iteration of the inner loop should deal with a column of the row.
Generally, you should not modify the loop counter outside the if
statement, as this is likely to make your code messy and hard to understand. There are only rare situations in which this is appropriate (and this is not one of them).
Also, comparing integers with floating point numbers is generally a bad idea, as floating-point numbers have limited precision. Therefore, they will often not be exactly equal, and the comparison will fail. For example, if you compare the integer 7
with 6.99999999998
, then the result of the comparison may be false, although the numbers are practically equal. When comparing floating-point values, you should generally allow for a certain tolerance, for example by determining whether the difference between the two values exceeds a certain threshold.
Here is a C89-compliant solution to the loop problem:
#include <stdio.h>
#define NUM_ROWS 4
#define NUM_COLS 4
int main( void )
{
int row, col;
for ( row = 0; row < NUM_ROWS; row++ )
{
// print first line containing only a static horizontal bar
printf( "|" );
for ( col = 0; col < NUM_COLS; col++ )
printf( "-----------------" );
printf( "\n" );
//print second line containing the variable information
for ( col = 0; col < NUM_COLS; col++ )
printf( "| row: %i, col: %i ", row, col );
//print vertical bar at end of line
printf( "|\n" );
}
//print static horizontal bar
printf( "|" );
for ( col = 0; col < NUM_COLS; col++ )
printf( "-----------------" );
printf( "\n" );
return 0;
}
The only thing not C89-compliant about the code above are the single-line comments (//
). You may have to replace them with multi-line comments (/*
and */
) if you want strict C89 compliance. However, most C89 compilers accept single-line comments as a language extension.
The above code contains a bit of code duplication. This code duplication can be removed, by breaking from inside the outer loop, like this:
#include <stdio.h>
#define NUM_ROWS 4
#define NUM_COLS 4
int main( void )
{
int row, col;
//NOTE: Leaving out the middle expression of the "for" statement
// will make it always true.
for ( row = 0; ; row++ )
{
// print first line containing only a static horizontal bar
printf( "|" );
for ( col = 0; col < NUM_COLS; col++ )
printf( "-----------------" );
printf( "\n" );
//break out of loop, if past last row
if ( row == NUM_ROWS )
break;
//print second line containing the variable information
for ( col = 0; col < NUM_COLS; col++ )
printf( "| row: %i, col: %i ", row, col );
//print vertical bar at end of line
printf( "|\n" );
}
return 0;
}
The code is now shorter (if you disregard the additional comment), but it may be a bit harder to understand.
Both of these programs print the following output:
|--------------------------------------------------------------------
| row: 0, col: 0 | row: 0, col: 1 | row: 0, col: 2 | row: 0, col: 3 |
|--------------------------------------------------------------------
| row: 1, col: 0 | row: 1, col: 1 | row: 1, col: 2 | row: 1, col: 3 |
|--------------------------------------------------------------------
| row: 2, col: 0 | row: 2, col: 1 | row: 2, col: 2 | row: 2, col: 3 |
|--------------------------------------------------------------------
| row: 3, col: 0 | row: 3, col: 1 | row: 3, col: 2 | row: 3, col: 3 |
|--------------------------------------------------------------------
Note that the formatting will no longer work properly if the numbers get higher than 10, because they will then require more space.
Regarding your second question on how to calculate the lines necessary to draw a 2D grid:
If you want to draw the lines of a 10*10
tile grid, then you will need to draw 11 horizontal lines and 11 vertical lines. You can generate the coordinates of these lines using the following logic:
#include <stdio.h>
#define PIXELS_PER_TILE 50
#define SIZE_X 10
#define SIZE_Y 10
int main( void )
{
int i;
printf( "Processing lines along X axis:\n" );
for ( i = 0; i <= SIZE_Y; i++ )
{
printf(
"Draw line from [%3d,%3d] to [%3d,%3d]\n",
0 * PIXELS_PER_TILE, i * PIXELS_PER_TILE,
SIZE_X * PIXELS_PER_TILE, i * PIXELS_PER_TILE
);
}
printf( "\nProcessing lines along Y axis:\n" );
for ( i = 0; i <= SIZE_X; i++ )
{
printf(
"Draw line from [%3d,%3d] to [%3d,%3d]\n",
i * PIXELS_PER_TILE, 0 * PIXELS_PER_TILE,
i * PIXELS_PER_TILE, SIZE_Y * PIXELS_PER_TILE
);
}
}
Here is the output of that program:
Processing lines along X axis:
Draw line from [ 0, 0] to [500, 0]
Draw line from [ 0, 50] to [500, 50]
Draw line from [ 0,100] to [500,100]
Draw line from [ 0,150] to [500,150]
Draw line from [ 0,200] to [500,200]
Draw line from [ 0,250] to [500,250]
Draw line from [ 0,300] to [500,300]
Draw line from [ 0,350] to [500,350]
Draw line from [ 0,400] to [500,400]
Draw line from [ 0,450] to [500,450]
Draw line from [ 0,500] to [500,500]
Processing lines along Y axis:
Draw line from [ 0, 0] to [ 0,500]
Draw line from [ 50, 0] to [ 50,500]
Draw line from [100, 0] to [100,500]
Draw line from [150, 0] to [150,500]
Draw line from [200, 0] to [200,500]
Draw line from [250, 0] to [250,500]
Draw line from [300, 0] to [300,500]
Draw line from [350, 0] to [350,500]
Draw line from [400, 0] to [400,500]
Draw line from [450, 0] to [450,500]
Draw line from [500, 0] to [500,500]
If you want to draw the lines of a 10*10*10
tile grid (i.e. a 3D grid), then you will need to draw 11*11
lines along the X-axis, 11*11
lines along the Y-axis, and 11*11
lines along the Z-axis (total 363 lines). You can generate the coordinates of these lines using the following logic:
#include <stdio.h>
#define PIXELS_PER_TILE 50
#define SIZE_X 10
#define SIZE_Y 10
#define SIZE_Z 10
int main( void )
{
int i;
int j;
printf( "Processing lines along X axis:\n" );
for ( i = 0; i <= SIZE_Y; i++ )
{
for ( j = 0; j <= SIZE_Z; j++ )
{
printf(
"Draw line from [%3d,%3d,%3d] to [%3d,%3d,%3d]\n",
0 * PIXELS_PER_TILE, i * PIXELS_PER_TILE, j * PIXELS_PER_TILE,
SIZE_X * PIXELS_PER_TILE, i * PIXELS_PER_TILE, j * PIXELS_PER_TILE
);
}
}
printf( "\nProcessing lines along Y axis:\n" );
for ( i = 0; i <= SIZE_X; i++ )
{
for ( j = 0; j <= SIZE_Z; j++ )
{
printf(
"Draw line from [%3d,%3d,%3d] to [%3d,%3d,%3d]\n",
i * PIXELS_PER_TILE, 0 * PIXELS_PER_TILE, j * PIXELS_PER_TILE,
i * PIXELS_PER_TILE, SIZE_Y * PIXELS_PER_TILE, j * PIXELS_PER_TILE
);
}
}
printf( "\nProcessing lines along Z axis:\n" );
for ( i = 0; i <= SIZE_X; i++ )
{
for ( j = 0; j <= SIZE_Y; j++ )
{
printf(
"Draw line from [%3d,%3d,%3d] to [%3d,%3d,%3d]\n",
i * PIXELS_PER_TILE, j * PIXELS_PER_TILE, 0 * PIXELS_PER_TILE,
i * PIXELS_PER_TILE, j * PIXELS_PER_TILE, SIZE_Z * PIXELS_PER_TILE
);
}
}
}
I won't post the output of this second program, because it will print several hundred lines of output.
Upvotes: 1