Grids, or matrixes, are a common data thingy, as information often appears in tables. Being able to fold, spindle, and mutilate a grid is a common computer programming task, something to entertain your idle hours even if you have no pressing need to manipulate a matrix.
Before I abuse a matrix/grid, it must be created. Two approaches are available: traditional array notation and pointer nightmare.
Array notation is easier, so it comes first:
2023_02_25-Lesson-a.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 3
int main()
{
int x,y;
int grid[SIZE][SIZE];
/* seed the randomizer */
srand( (unsigned)time(NULL) );
/* populate the grid */
for( x=0; x<SIZE; x++ )
for( y=0; y<SIZE; y++ )
grid[x][y] = rand()%10 + 1;
/* output the grid */
for( x=0; x<SIZE; x++ )
{
for( y=0; y<SIZE; y++ )
printf(" %d ",grid[x][y]);
putchar('\n');
}
return(0);
}
The defined constant SIZE sets the grid’s row and column count — a square. In this example, the matrix is 3×3 (or SIZE x SIZE) integers, which is how the grid[][] two-dimensional array is declared at Line 10.
After seeding the randomizer, nested for loops populate the grid: rows (variable x) by columns (variable y). Random values in the range of 1 through 10 populate the matrix: rand()%10 + 1
A second set of nested for loops outputs the grid, setting a newline between each row.
Here’s a sample run:
4 7 1
2 3 7
8 5 9
As I’m fond of writing, a two-dimensional array is merely a one-dimensional array all gussied up for programmer readability. Honestly, it’s all one chunk of data in memory anyway. But the double bracket notation makes things easier to read — as long as you don’t forget that the first array element is zero, not one.
To pervert the same code into a pointer version, I rely upon the assumption that the matrix is just one long chunk of data. The same SIZE constant defines the dimensions and manipulates the data as a matrix. The code is a little tighter in some spots, but requires more statements as the matrix buffer must be allocated.
2023_02_25-Lesson-b.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 3
int main()
{
int x;
int *grid;
/* seed the randomizer */
srand( (unsigned)time(NULL) );
/* allocate the grid */
grid = malloc( sizeof(int) * SIZE * SIZE );
if( grid==NULL )
{
fprintf(stderr,"Unable to allocate memory\n");
exit(1);
}
/* populate the grid */
for( x=0; x<SIZE*SIZE; x++ )
*(grid+x) = rand()%10 + 1;
/* output the grid */
for( x=0; x<SIZE*SIZE; x++ )
{
printf(" %d ",*(grid+x));
if( (x+1)%3 == 0 )
putchar('\n');
}
free(grid);
return(0);
}
Storage is allocated at Line 16, assigned to int pointer variable grid:
grid = malloc( sizeof(int) * SIZE * SIZE );
The SIZE * SIZE calculation allocates the same size as the two-dimensional array. Then a test is made to ensure storage was successfully allocated.
Only a single for loop is required to assign values to the matrix, again using SIZE*SIZE to set the quantity of integers required. The expression *(grid+x) ensures that the values are set at the proper offset.
A single for loop is all that’s needed to output the matrix. An if statement determines when SIZE items are output — if( (x+1)%3 == 0 ) — at the end of a row, a newline is output. Here’s the sample run:
1 8 5
9 7 3
5 3 1
Yes, it’s the same output, just a different approach. Either way, the matrix is created and prepped for abuse.
For next week’s Lesson, the task is to total each of the rows and columns.