Describing Complex Data – Solution

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.

2 thoughts on “Describing Complex Data – Solution

  1. 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;

  2. 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.

Leave a Reply