-1

Hi guys I've been trying to solve a multiplication in C. I'm having a problem to get an element in the array of arrays of Integer.By now, I can only access just the first row of Array A[][], but the other values are not ok. Here is the code snippet, problem is in matrixProduct method:

int fa,ca,fb,cb=0;

int main(){
    int A[20][20], B[20][20]. C[20][20];
    printf("Rows for A: ");
    scanf("%d",&fa);
    printf("\nColumns for A: ");
    scanf("%d",&ca);
    printf("\nRows for B: ");
    scanf("%d", &fb);
    printf("\nColumns for B: ");
    scanf("%d",&cb);
    if (ca!=fb){
        printf("\nOperation not available");
        return 0;
    }else{//Filling matrix A & B
        int i,j;
        for (i=0; i<fa; i++){
            for(j=0;j<ca;j++){
                printf("Element at position A[%d][%d]: ",i,j);
                scanf("%d",&A[i][j]);
            }
        }
        for (i=0; i<fb; i++){
            for(j=0;j<cb;j++){
                printf("Element at position B[%d][%d]: ",i,j);
                scanf("%d",&B[i][j]);
            }
        }
    }
    int k=productoMatriz(A,B);

    return 0;
}

//Parameters two matrixes A,B 
int matrixProduct(int A[fa][ca],int B[fb][cb]){
    int i,j,k=0;
    int C[20][20];
    for (i=0; i<fa; i++){
            for(j=0;j<cb;j++){
                C[i][j]=0;
            }
    }
    for(i=0;i<fa;i++){
        for(j=0;j<cb;j++){
                printf(" A [%d] [%d] = %d\n",i,j,A[i][j]);//Problem is in here works
        //ok for the first row but then it doesnt!
            for(k=0;k<ca;k++){
        //C[i][j]=A[i][k]*B[k][j];
            }
        }
    }
    printf("\n\nC Matrix:\n");
    for(i=0; i<fa; i++)
    for(j=0; j<cb; j++)
    {
    printf("%d  ",C[i][j]);
    if(j==cb-1)
        printf("\n\n");
    }
    return 0;
}

Edit

Now I've changed the 20's values to macros and change the parameter in the matrixProduct but now Im trying to return the C value in the main method with something like this and then print it in other method void printMatrix(int C[MAXSIZE][MAXSIZE]):

C[MAXSIZE][MAXSIZE]=matrixProduct(A,B);
printMatrix(C);

Again I'm getting wrong values...

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
user3538081
  • 43
  • 1
  • 5

3 Answers3

3

The problem is here:

int matrixProduct(int A[fa][ca],int B[fb][cb]){

Your function prototype expects int [fa][ca] and int [fb][cb], but you're passing in int [20][20] and int [20][20]. These are objects of different sizes and therefore when you attempt to access the array elements it pulls from the wrong address.

A two dimensional array is laid out with each row following the next. So if you have int A[2][2] it looks like this:

|  0  |  1  |  2  |  3  |
 [0,0] [0,1] [1,0] [1,1]

Similarly if you have int A[3][3] it looks like this:

|  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |
 [0,0] [0,1] [0,2] [1,0] [1,1] [1,2] [2,0] [2,1] [2,2]

In the first case, [1,0] is at the third byte while in the second case it as at the fourth byte.

Edit:

Addressing your edit, this won't work:

C[MAXSIZE][MAXSIZE]=matrixProduct(A,B);

Because you can't return an array from a function. What you need to do instead is pass in the 2D array C as a parameter. Because arrays are passed to functions as a pointer to the first element, changes made to the array are reflected outside of the function.

dbush
  • 205,898
  • 23
  • 218
  • 273
2

The problem is that you are passing a fixed-size 20 by 20 arrays for variable-size fa by ca and fb by cb arrays. This is not allowed: the way you accept your arrays should be the same as the way in which the arrays are declared:

int matrixProduct(int A[20][20], int B[20][20])

Otherwise, the compiler is going to access data from wrong places in memory, causing undefined behavior.

Alternatively, you could move the declaration of A and B inside main to a point after fa, ca, fb, and cb are read, and declare them in the same way as you declared them in the header of matrixProduct function.

In addition, it looks like the matrixProduct function is lacking a prototype. You should be getting a warning to that effect.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

Other answers may point your wrong. But according to me, here are points that

  • For printing you don't need return functions.
  • So, void functions should be used.
  • You should use macro to specify size of arrays. Because when you want to increase or decrease size of arrays it will make convenient.
  • First dimension's size may not be written in prototypes and parameters. But second must.
  • Whenever possible and useful situtations, try to make function.
  • You wanted to return with 0, it is okey but for error handling you should choose another number like -1.
  • Whenever possible avoid global variables ! Why?
  • I also recommend that declare function prototypes before define functions because if you write wrong type of variable or miss, compiler warns you.
  • You can use the code but review your wrongs.

I've tried to improve your code

#include <stdio.h>

#define SIZE 20

void take_data(int a[][SIZE], int b[][SIZE], int fa,int ca, int fb, int cb);
void multiplication(int a[][SIZE],int b[][SIZE],int mult[][SIZE],int fa,int ca,int fb,int cb);
void display(int mult[][SIZE], int fa, int cb);

int main()
{
    int a[SIZE][SIZE], b[SIZE][SIZE], mult[SIZE][SIZE], fa, ca, fb, cb;
    printf("Enter rows and column for first matrix: ");
    scanf("%d%d", &fa, &ca);
    printf("Enter rows and column for second matrix: ");
    scanf("%d%d",&fb, &cb);

    /* If colum of first matrix in not equal to row of second matrix, asking user to enter the size of matrix again. */

    while (ca!=fb)
    {
        printf("Error! column of first matrix not equal to row of second.\n");
        printf("Enter rows and column for first matrix: ");
        scanf("%d%d", &fa, &ca);
        printf("Enter rows and column for second matrix: ");
        scanf("%d%d",&fb, &cb);
    }
    take_data(a,b,fa,ca,fb,cb);  /* Function to take matices data */
    multiplication(a,b,mult,fa,ca,fb,cb); /* Function to multiply two matrices. */
    display(mult,fa,cb); /* Function to display resultant matrix after multiplication. */
    return 0;
}

void take_data(int a[][SIZE], int b[][SIZE], int fa,int ca, int fb, int cb)
{
    int i,j;
    printf("\nEnter elements of matrix 1:\n");
    for(i=0; i<fa; ++i)
        for(j=0; j<ca; ++j)
        {
            printf("Enter elements a%d%d: ",i+1,j+1);
            scanf("%d",&a[i][j]);
        }

    printf("\nEnter elements of matrix 2:\n");
    for(i=0; i<fb; ++i)
        for(j=0; j<cb; ++j)
        {
            printf("Enter elements b%d%d: ",i+1,j+1);
            scanf("%d",&b[i][j]);
        }
}

void multiplication(int a[][SIZE],int b[][SIZE],int mult[][SIZE],int fa,int ca,int fb,int cb)
{
    int i,j,k;
    /* Initializing elements of matrix mult to 0.*/
    for(i=0; i<fa; ++i)
        for(j=0; j<cb; ++j)
        {
            mult[i][j]=0;
        }
    /* Multiplying matrix a and b and storing in array mult. */
    for(i=0; i<fa; ++i)
        for(j=0; j<cb; ++j)
            for(k=0; k<ca; ++k)
            {
                mult[i][j]+=a[i][k]*b[k][j];
            }
}

void display(int mult[][SIZE], int fa, int cb)
{
    int i, j;
    printf("\nOutput Matrix:\n");
    for(i=0; i<fa; ++i)
        for(j=0; j<cb; ++j)
        {
            printf("%d  ",mult[i][j]);
            if(j==cb-1)
                printf("\n\n");
        }
}

We need to use malloc() to return array and don't forget free it.With return array

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


#define SIZE 20

void take_data(int a[][SIZE], int b[][SIZE], int fa,int ca, int fb, int cb);
int** multiplication(int a[][SIZE],int b[][SIZE],int fa,int ca,int fb,int cb);
void display(int fa, int cb, int** mult);
void free_mult(int **mult, int Rows);


int main()
{
    int a[SIZE][SIZE], b[SIZE][SIZE], fa, ca, fb, cb;
    int** mult;
    printf("Enter rows and column for first matrix: ");
    scanf("%d%d", &fa, &ca);
    printf("Enter rows and column for second matrix: ");
    scanf("%d%d",&fb, &cb);

    /* If colum of first matrix in not equal to row of second matrix, asking user to enter the size of matrix again. */

    while (ca!=fb)
    {
        printf("Error! column of first matrix not equal to row of second.\n");
        printf("Enter rows and column for first matrix: ");
        scanf("%d%d", &fa, &ca);
        printf("Enter rows and column for second matrix: ");
        scanf("%d%d",&fb, &cb);
    }
    take_data(a,b,fa,ca,fb,cb);  /* Function to take matices data */
    mult = multiplication(a,b,fa,ca,fb,cb); /* Function to multiply two matrices. */
    display(fa,cb,mult); /* Function to display resultant matrix after multiplication. */

    free_mult(mult, fa);

    return 0;
}

void take_data(int a[][SIZE], int b[][SIZE], int fa,int ca, int fb, int cb)
{
    int i,j;
    printf("\nEnter elements of matrix 1:\n");
    for(i=0; i<fa; ++i)
        for(j=0; j<ca; ++j)
        {
            printf("Enter elements a%d%d: ",i+1,j+1);
            scanf("%d",&a[i][j]);
        }

    printf("\nEnter elements of matrix 2:\n");
    for(i=0; i<fb; ++i)
        for(j=0; j<cb; ++j)
        {
            printf("Enter elements b%d%d: ",i+1,j+1);
            scanf("%d",&b[i][j]);
        }
}

int** multiplication(int a[][SIZE],int b[][SIZE],int fa,int ca,int fb,int cb)
{
    int i,j,k;


    int **mult = (int **)malloc(fa * sizeof(int *));
    int row;
    // for each row allocate Cols ints
    for (row = 0; row < fa; row++) {
        mult[row] = (int *)malloc(fa * sizeof(int));
    }


    /* Initializing elements of matrix mult to 0.*/
    for(i=0; i<fa; ++i)
        for(j=0; j<cb; ++j)
        {
            mult[i][j]=0;
        }
    /* Multiplying matrix a and b and storing in array mult. */
    for(i=0; i<fa; ++i)
        for(j=0; j<cb; ++j)
            for(k=0; k<ca; ++k)
            {
                mult[i][j]+=a[i][k]*b[k][j];
            }
    return mult;
}

void display(int fa, int cb, int** mult)
{
    int i, j;
    printf("\nOutput Matrix:\n");
    for(i=0; i<fa; ++i)
        for(j=0; j<cb; ++j)
        {
            printf("%d  ",mult[i][j]);
            if(j==cb-1)
                printf("\n\n");
        }
}

void free_mult(int **mult, int Rows)
{
    int row;

    // first free each row
    for (row = 0; row < Rows; row++) {
        free(mult[row]);
    }

    // Eventually free the memory of the pointers to the rows
    free(mult);
}
Community
  • 1
  • 1
  • This may be good advices for a newbie programmer, but it does not really address the OP issue. – Holt Aug 10 '15 at 20:02
  • When I was writing the answer, I had alredy seen the other answers. Why should I have prefered to write same answers ? @Holt – Soner from The Ottoman Empire Aug 10 '15 at 20:08
  • If you have nothing to add to the current answer which would help the op solving his problem, then you should have upvoted the answer you found the most useful and commented to explain what can be improved. If you did not found any of these useful, you should have written your own answer to the op question, and not some kind of off-topic advices (You could have added these advices to your answer if you wanted to). – Holt Aug 10 '15 at 20:16
  • Thank you @itsnotmyrealname ! Btw I wanted to return the C array thats the reason I had return 0 for the moment, so if want to do this I could make something like.... int matrix(...){ .... return C; } and call it in the main method as int C=matrixProduct(A,B);??? – user3538081 Aug 10 '15 at 20:56
  • Yeah @itsnotmyrealname thats right, but, the way I wrote the C returning matrix in this answer , would work with a method like ... void printMatrix(int C[MAXSIZE][MAXSIZE])? – user3538081 Aug 10 '15 at 21:14
  • @itsnotmyrealname ready! I edited my answer and gave you the tick! – user3538081 Aug 10 '15 at 21:51
  • ordinary meatspice people talking I don't need your advices live your life @Holt – Soner from The Ottoman Empire Aug 10 '15 at 22:17