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.