5

Well, I am doing matrix multiplication and I need to make an m x n array and a p x q array.
However, I do not know how to.

Here is my program which prints correct output when I feed in values manually:

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

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[]) {
    /*
        Rows and columns for matrices.
    */
    int m , n; // rows and columns of the first matrix
    int p , q; // rows and columns of the second matrix

    /*
        1st matrix is a 2x3 matrix
    */
    m = 2;
    n = 3;

    /*
        2nd matrix is a 3x2 matrix
    */
    p = 3;
    q = 2;


    /*
        Create the matrices.
        Give them values.
    */
    int matrix1[m][n] = {
                            {2,3,4},
                            {5,6,7}
                        };
    int matrix2[p][q] = {
                            {1,7},
                            {3,9},
                            {5,11}
                        };

    /*
        Check if we can multiple the matrices.
        For matrix multiplication,
        the number of COLUMNS of FIRST matrix must be equal to
        the number of ROWS of SECOND matrix
    */
    if(n==p){
        /*
            Create a new matrix.
            The resulting matrix will have M rows and Q columns.
            That is, the matrix is a MxQ matrix.
        */
        int matrix3[2][2]; 

        /*
            We need three loops so we have 3 variables.
        */
        int i = 0; // iterates over matrix1 rows
        int j = 0; // iterates over matrix1 columns
        int k = 0; // iterates over matrix2 rows
        int l = 0; // iterates over matrix2 columns


        while(i < m){
            l = 0;
            while(l < q){
                int element = 0;
                while(j < n && k < p){
                    element += matrix1[i][j] * matrix2[k][l];
                    matrix3[i][l] = element;
                    j++;
                    k++;
                }
                printf("\t%d",element);
                l++;
                j = 0;
                k = 0;
            }
            printf("\n");
            i++;
        }

    }else{
        printf("Matrices can not be multiplied");
    }
}  

The matrix declaration gets flagged as an error. How do I solve it?

6
  • Does your compiler support VLAs ? And check your error. VLAs, even if supported, do not support initializers. Commented Sep 21, 2013 at 19:46
  • @WhozCraig What ? :-/ VLA = Variable Length Array. I use Dev-C++ which uses GCC V 4.71 Commented Sep 21, 2013 at 19:46
  • 3
    There isn't even a need for VLAs in this code. the matrices can be const-sized. Commented Sep 21, 2013 at 19:47
  • @WhozCraig yes, but .. I just need to show the instructor that I can do it for any given input matrix :) Easy in Java, you know :) Commented Sep 21, 2013 at 19:47
  • If you're doing this for any given input you better have an alternative method for populating those arrays than static initialization. But identify the original error message please. exactly what does is say (update the question please, to include it). It is likely as I described, VLAs don't support initialization (assuming your compiler supports VLAs, which is testable via macro). Commented Sep 21, 2013 at 19:48

3 Answers 3

4

How do I solve it?

In first place, by not using a VLA. You don't need VLAs for this particular task.

As to what the actual problem is: variable-length arrays cannot be initialized. You have to assign to their elements one-by-one or use some mass-"assignment" technique such as memcpy().

Sign up to request clarification or add additional context in comments.

5 Comments

hi there, Carbonic Acid. I figured that out. I cannot use VLA :(
@LittleChild Um, what I'm saying is that it doesn't matter whether or not you can -- you simply don't need them. Declare your array as int mat[2][3] and boom, you can suddenly initialize it.
I know I can if I do it that way. I can do that using Macros, too. But same as punching in values myself :)
@L Is your real problem getting user input then?
@LittleChild I beleive you have a XY
1

Is it an option to use C99?

Variable Length Arrays

This is 100% valid in C99:

  int m = 2;
  int n = 3;

  int matrix1[m][n];

4 Comments

I do not know. Data Structures is being taught in C in the Uni so my knowledge is limited to what I need to write basic programs :)
C99 is the last version of C, and it supports VLA. I believe you should ask @LittleChild. Updated my answer with a link of C99 description.
"This is 100% valid in C99" - no, it isn't, one cannot initialize VLAs. Only statically-sized arrays can be initialized.
Expect a stack overflow as soon as you operate on real world sized matrices. VLAs are a bad fit for this problem.
1

'Native' variable length arrays are, according the the current c standard, an optional language construct. You'll have to check your compiler documentation to determine if the compiler you're using has any support for variable length arrays.

Prior to C99 variable length arrays need to be explicitly allocated on the heap and accessed via a pointer. For the matrix problem you have two options.

The first is to allocate an array with sufficient storage, and calculate the correct indices when you need to read or modify a matrix element. For example:

int* matrix_storage = malloc( sizeof( int ) * matrix_width * matrix_height );
// set row 0, column 1 to 0
matrix_storage[ ( 0 * matrix_width ) + ( 1 % matrix_width ) ] = 0; 

Alternatively you can allocate an array of pointers to each row or column:

int** rows = malloc( sizeof( (int*) ) * matrix_height );
for( int i = 0; i < matrix_height; ++i )
{
    rows[i] = malloc( sizeof(int) * matrix_width );
}
row[0][1] = 0; // set row 0, column 1 to 0

This implementation wastes some memory, regardless of the implementation you choose consider using functions and the struct keyword to hide the implementation from the driver code (the code that is actually mutating or reading the matrices).

Some notes: I have used c99 for loop syntax, with older compilers the int i variable will need to be declared outside the for loop. Also note that if your matrix size can be determined at compile time (IE does not rely on user input) you don't need the overhead of malloc and can hard code your array size. The example code you have posted does not require dynamic allocation.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.