4
\$\begingroup\$

This exercise surprised me a little bit. I did not expect that gcc (GCC 6.3.0 in the MinGW suite) would use the C11 standard by default, which I realised after I read the documentation. Here's the code that compiles without any errors or warnings:

matrix.c

#include <stdio.h>
#include <stdlib.h>

void input(int m, int n, int a[m][n])
{
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d, %d : ", i, j);
            scanf("%d", &a[i][j]);
        }
    }
}

void print(int m, int n, int a[m][n])
{
    int i, j;
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            printf("%3d ", a[i][j]);
        }
        printf("\n");
    }   
}

void multiply(int m, int n, int p, int a[m][n], int b[n][p], int c[m][p])
{
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < p; j++) {
            c[i][j] = 0;
            for (int k = 0; k < n; k++) {
                c[i][j] += a[i][k] * b[k][j];
            }
        }
    }
}

int main()
{
    int r1, c1, r2, c2;
    printf("Row and column for matrix #1 :\n");
    scanf("%d %d", &r1, &c1);
    printf("Row and column for matrix #2 :\n");
    scanf("%d %d", &r2, &c2);

    if (r2 != c1) {
        printf("The matrices are incompatible.\n");
        exit(EXIT_FAILURE);
    }

    int mat1[r1][c1], mat2[r2][c2], ans[r1][c2];
    printf("Enter elements of the first matrix.\n");
    input(r1, c1, mat1);
    printf("The elements of the first matrix are :\n");
    print(r1, c1, mat1);
    printf("Enter elements of the second matrix.\n");
    input(r2, c2, mat2);
    printf("The elements of the second matrix are :\n");
    print(r2, c2, mat2);

    multiply(r1, r2, c2, mat1, mat2, ans);
    printf("The product is :\n");
    print(r1, c2, ans);

    return EXIT_SUCCESS;
}

Feedback and criticism on any and all aspects are welcome.

\$\endgroup\$
  • \$\begingroup\$ Can this code even work? The functions expect a two-dimensional array, and you pass a one-dimensional to them. This is a tricky part of the C language. Defining a struct helps against that. \$\endgroup\$ – Roland Illig Oct 29 '17 at 11:18
  • 1
    \$\begingroup\$ I personally find this a celebration of progress. Extremely clean and simple thanks to C11. I fail to see how is C98 "solution" better or simpler? \$\endgroup\$ – DBJDBJ Feb 25 at 6:20
5
\$\begingroup\$

I suggest you roll an explicit matrix type. For example:

typedef struct matrix_t {
    size_t rows;
    size_t cols;
    int* data;
} matrix_t;

void matrix_t_multiply(matrix_t* left, matrix_t* right, matrix_t* result) {
    ...
}
\$\endgroup\$
  • \$\begingroup\$ I've read some posts that propagate against the use of typedef structs. Do they have a valid reason to do so? I personally find this soution elegant. \$\endgroup\$ – Hungry Blue Dev Oct 30 '17 at 20:07
  • 2
    \$\begingroup\$ @Astrobleme A matter of taste, and it is said that arguing about such is insane. \$\endgroup\$ – coderodde Oct 30 '17 at 22:48
  • 2
    \$\begingroup\$ @Astrobleme, you may have been reading reviews of C++ code, where the typedef provides no additional function (the structure tag is automatically also its name in C++, but not in C). \$\endgroup\$ – Toby Speight Oct 31 '17 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.