In the C language, a structure is used to express complex data types. The structure contains members that describe different parts of this complex data, such as a matrix required in this month’s Exercise.
For my solution, I created the following structure.
struct matrix {
int *grid;
int columns;
int rows;
};
The structure contains three members: grid
is a pointer, the base of an array that contains the matrix’s data (integers); columns
, the number of columns; and rows
, the number of rows. Together, rows
× columns
defines the size of the matrix.
It’s possible to assign a single-dimension array to a pointer, which makes it easy to create this structure using the two matrixes presented in the challenge post. Here is my solution, including the output() function:
2024_09-Exercise.c
#include <stdio.h>
struct matrix {
int *grid;
int columns;
int rows;
};
void output(char *title,struct matrix m)
{
int x,y;
puts(title);
for( y=0; y<m.rows; y++ )
{
for( x=0; x<m.columns; x++ )
{
printf(" %3d ",*(m.grid+x+y*m.columns) );
}
putchar('\n');
}
}
int main()
{
int matrix_a[12] = {
10, 20, 30, 40,
11, 21, 31, 41,
12, 22, 32, 42
};
int matrix_b[4] = {
1, 2,
3, 4
};
struct matrix a = { matrix_a, 4, 3 };
struct matrix b = { matrix_b, 2, 2 };
/* output each matrix */
output("Matrix A",a);
output("Matrix B",b);
return 0;
}
Each matrix is defined as an integer array in the main() function. The next two statements assign values to the matrix structures a
and b
:
struct matrix a = { matrix_a, 4, 3 };
struct matrix b = { matrix_b, 2, 2 };
My version of the output() function has two arguments: The first is a title string, the second the structure defining the matrix. The function outputs the title first, then uses a nested loop to output the rows and column values.
To find offsets in the array, which is now a pointer, the following expression is used:
*(m.grid+x+y*m.columns)
The row values are held in m.rows
, which defines the outer loop (variable y
). Each row consists of column values stored in m.columns
. The values are offset from the array’s base, m.grid
. Add the row offset plus the row count times the number of columns to obtain each element in the matrix.
Here’s the output:
Matrix A
10 20 30 40
11 21 31 41
12 22 32 42
Matrix B
1 2
3 4
I hope your solution met with success and you’re able to use a structure to describe a matrix. By using this technique, you can manipulate the matrix in various ways without having to rely upon or assume that the grid is square.
For next month’s Exercise, I continue this exploration with some matrix manipulation.
I wonder whether for purposes of printing and carrying out arithmetic it would be easier to use 2D arrays, eg:
int matrix_a[3][4]
The bit of code
(m.grid+x+y*m.columns)
might be a bit cumbersome for repeated use so as an alternative to 2D arrays it could be moved to a separate function, eg.
int value(matrix, row, column)
return matrix.grid + column + row * matrix.columns;
The problem lies with passing the arrays. It just gets funky converting 2D arrays to pointers.
Further, the expression I use (
m.grid+x+y*m.columns
) can fail because it creates duplicate references as offsets. For example, position 12 in the grid could be row 3 column 4 AND row 4 column 3.’tis a puzzle.