#include <stdio.h>



















void mul( size_t m,
        size_t n, size_t p,
        float res[m][n],
        float lhs[m][p],
        float rhs[p][n] ) {
    for ( size_t i = 0;
            i < m; i++ )
        for ( size_t j = 0;
                j < n; j++ ) {
            res[i][j] = 0.0;
            for ( size_t k = 0;
                    k < p; k++ )
                @res[i][j] +=@
                    @lhs[i][k] *@
                    @rhs[k][j];@
        }
}









#ifdef RUNIT


static void zero( size_t r, size_t c, float mat[r][c] ) {
    for ( size_t i = 0; i < r; i++ )
        for ( size_t j = 0; j < c; j++ )
            mat[i][j] = 0.0;
}


static void fill( size_t r, size_t c, float mat[r][c] ) {
    for ( size_t i = 0; i < r; i++ )
        for ( size_t j = 0; j < c; j++ )
            mat[i][j] = 1.0 * (i + 1) + 0.1 * (j+1);
}


static void print( size_t r, size_t c, float mat[r][c] ) {
    for ( size_t i = 0; i < r; i++ ) {
        for ( size_t j = 0; j < c; j++ )
            printf("%2g ", mat[i][j]);
        printf("\n");
    }
}

#define EXPSZ_M 2
#define EXPSZ_N 3
#define EXPSZ_P 4


int main() {
    float res[ EXPSZ_M ][ EXPSZ_N ];  zero( EXPSZ_M, EXPSZ_N, res );
    float lhs[ EXPSZ_M ][ EXPSZ_P ];  fill( EXPSZ_M, EXPSZ_P, lhs );
    float rhs[ EXPSZ_P ][ EXPSZ_N ];  fill( EXPSZ_P, EXPSZ_N, rhs );
    mul( EXPSZ_M, EXPSZ_N, EXPSZ_P, res, lhs, rhs );
    print(EXPSZ_M, EXPSZ_P, lhs);
    printf("*\n");
    print(EXPSZ_P, EXPSZ_N, rhs);
    printf("=\n");
    print(EXPSZ_M, EXPSZ_N, res);
}



#endif
