简体   繁体   English

c 中的二维矩阵乘法

[英]2D matrix multiplication in c

I have written a code in C language for matrix multiplication.我用 C 语言编写了用于矩阵乘法的代码。 There is no error, but the desired output is not coming, which part of my code is wrong or had I miss something.没有错误,但是所需的 output 没有出现,我的代码的哪一部分是错误的或者我错过了什么。

在此处输入图像描述

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

int main() {
    int r1, c1, r2, c2;
    int a[r1][c1];
    int b[r2][c2];
    int c[r1][c2];
    int i, j;
    printf("enter row1 and col1:\n");
    scanf("%d%d", &r1, &c1);
    printf("enter row2 and col2:\n");
    scanf("%d%d", &r2, &c2);
    if (c1 == r2) {
        printf("enter element of 1st matrix:");
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c1; j++) {
                scanf("%d", &a[i][j]);
            }
        }
        printf("\n-----------------");
        printf("enter element of 2nd matrix:");
        for (i = 0; i < r2; i++) {
            for (j = 0; j < c2; j++) {
                scanf("%d", &b[i][j]);
            }
        }
    
        printf("the resultant matrix is:\n");
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c2; j++) {
                c[i][j] += a[i][j] * b[j][i];
            }
        }
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c2; j++) {
                printf("%d\t", c[i][j]);
            }
            printf("\n\n");
        }
    }
    return 0;
}

There are multiple problems in the code:代码中存在多个问题:

  • the arrays int a[r1][c1]; arrays int a[r1][c1]; , int b[r2][c2]; , int b[r2][c2]; , int c[r1][c2]; , int c[r1][c2]; are defined before r1 and c1 have been read from the user: the code has potential undefined behavior as r1 and c1 are uninitialized, thus have indeterminate values: the allocation of the arrays may fail or cause undefined behavior if the sizes happen to be negative and accessing them with index values iterating up to different boundary values entered by the user will have undefined behavior.在从用户读取r1c1之前定义:代码具有潜在的未定义行为,因为r1c1未初始化,因此具有不确定的值:如果大小恰好为负数,则 arrays 的分配可能会失败或导致未定义的行为使用迭代到用户输入的不同边界值的索引值访问它们将具有未定义的行为。

  • you verify that the number of columns of a is equal to the number of rows of b , but you should also check that all dimensions are positive to avoid potential undefined behavior.您验证a的列数是否等于b的行数,但您还应该检查所有维度是否为正以避免潜在的未定义行为。

  • Defining the matrices as variable length arrays with automatic storage is risky: large sizes may cause a stack overflow .将矩阵定义为具有自动存储的可变长度 arrays 是有风险的:大尺寸可能会导致堆栈溢出 Allocating the matrices from the heap is recommended.建议从堆中分配矩阵。

  • the multiplication algorithm is incorrect: you must implement a triple loop and initialize the target element at c1[i][j] before the inner loop.乘法算法不正确:您必须实现三重循环并在内循环之前在c1[i][j]处初始化目标元素。

Here is a modified version:这是修改后的版本:

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

int main() {
    int r1, c1, r2, c2;
    printf("enter row1 and col1:\n");
    if (scanf("%d%d", &r1, &c1) != 2)
        return 1;
    printf("enter row2 and col2:\n");
    if (scanf("%d%d", &r2, &c2) != 2)
        return 1;
    if (r1 <= 0 || c1 <= 0 || r2 <= 0 || c2 <= 0 || c1 != r2) {
        printf("invalid matrix sizes\n");
        return 1;
    } else {
#if !defined ALLOCATE_MATRICES_FROM_THE_HEAP
        // if the dimensions are small, you can define the matrices as
        int a[r1][c1], b[r2][c2], c[r1][c2];
#else
        // for large sizes, you can allocate the matrices from the heap this way:
        int (*a)[c1] = calloc(sizeof(*a), r1);
        int (*b)[c2] = calloc(sizeof(*b), r2);
        int (*c)[c2] = calloc(sizeof(*c), r1);
        if (a == NULL || b == NULL || c == NULL) {
            printf("out of memory\n");
            return 1;
        }
#endif
        printf("enter elements of 1st matrix:");
        for (int i = 0; i < r1; i++) {
            for (int j = 0; j < c1; j++) {
                a[i][j] = 0;
                scanf("%d", &a[i][j]);
            }
        }
        printf("\n-----------------");
        printf("enter elements of 2nd matrix:");
        for (int i = 0; i < r2; i++) {
            for (int j = 0; j < c2; j++) {
                b[i][j] = 0;
                scanf("%d", &b[i][j]);
            }
        }
    
        printf("the resultant matrix is:\n");
        for (int i = 0; i < r1; i++) {
            for (int j = 0; j < c2; j++) {
                int v = 0;
                for (int k = 0; k < c1; k++) {
                    v += a[i][k] * b[k][j];
                }
                c[i][j] = v;
            }
        }
        for (int i = 0; i < r1; i++) {
            for (int j = 0; j < c2; j++) {
                printf("%5d\t", c[i][j]);
            }
            printf("\n\n");
        }
#if defined ALLOCATE_MATRICES_FROM_THE_HEAP
        free(a);
        free(b);
        free(c);
#endif
        return 0;
    }
}

The problem is here:问题在这里:

int r1, c1, r2, c2;
int a[r1][c1];   // at this point r1 c1, r2, c2 etc.
int b[r2][c2];   // are not yet initialized and their
int c[r1][c2];   // content is undetermined. Therefore
                 // the size of the arrays a, b and C are
                 // undetermined leading to the problem you encounter

You want this:你要这个:

int r1,c1,r2,c2;
int i,j;
printf("enter row1 and col1:\n");
scanf("%d%d",&r1,&c1);
printf("enter row2 and col2:\n");
scanf("%d%d",&r2,&c2);

int a[r1][c1];  // here r1, c1, r2, c2 etc.
int b[r2][c2];  // have determined values
int c[r1][c2];

There might be more problems further in your code, I didn't check.您的代码中可能还有更多问题,我没有检查。

The program you post dimensions the three matrices with undefined values coming from uninitialized variables.您发布的程序为来自未初始化变量的未定义值的三个矩阵提供维度。 You can, at least, dimension those variables once you know the values of the dimensions, as in (please, read my comments in your code, as they state problems in your code you have not realized):一旦您知道维度的值,您至少可以对这些变量进行标注,如下所示(请阅读我在您的代码中的注释,因为它们在您的代码中出现了 state 问题,您还没有意识到):

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

int main()
{
    int r1, c1, r2, c2;
    int i, j;
    printf("enter row1 and col1:\n");
    scanf("%d%d", &r1, &c1);
    printf("enter row2 and col2:\n");
    scanf("%d%d", &r2, &c2);
    int a[r1][c1];  /* declare the dimensions <<<after>>> you know what values are */
    int b[r2][c2];  /* to be given. */
    int c[r1][c2];

    if (c1 == r2) { /* put an else statement to this if indicating the cause of */
            /* not making any calculation in case r2 and c1 not being equal */
        printf("enter element of 1st matrix:");
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c1; j++) {
                scanf("%d", &a[i][j]);
            }
        }
        printf("\n-----------------");
        printf("enter element of 2nd matrix:");
        for (i = 0; i < r2; i++) {
            for (j = 0; j < c2; j++) {
                scanf("%d", &b[i][j]);
            }
        }
    
        printf("the resultant matrix is:\n");
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c2; j++) { /* you need three nested loops, not two */
                /* ALL YOUR CODE HERE IS BAD, USE THIS INSTEAD */
                int k;
                c[i][j] = 0; /* initialize c[i][j] to zero or you'll get weird values */
                for (k = 0; k < c1; k++) { /* YOU NEED ANOTHER LOOP */
                    c[i][j] += a[i][k] * b[k][j];
                }
            }
        }
        for (i = 0; i < r1; i++) {
            for (j = 0; j < c2; j++) {
                printf("%d\t", c[i][j]);
            }
            printf("\n\n");
        }
    }
    return 0;
}

but it is more portable to give your matrices maximum dimensions and work only in the subbox delimited by the values of r1 , c1 , r2 , c2 , r3 and c3 .但是为矩阵提供最大尺寸并仅在由r1c1r2c2r3c3的值分隔的子框中工作更便于携带。 As in:如:

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

#define MAX_DIM 10

int main()
{
    int r1, c1, r2, c2;
    int i, j; /* why didn't you call these r and c (for row and column resp.)? */

    /* this will loop on input until you give correct values for all dimensions, */
    do {
        printf("enter row1 and col1:\n");
        scanf("%d%d", &r1, &c1);
        printf("enter row2 and col2:\n");
        scanf("%d%d", &r2, &c2);
    } while (r1 <= 0 || r1 > MAX_DIM || c1 <= 0 || c1 > MAX_DIM ||
             r2 <= 0 || r2 > MAX_DIM || c2 <= 0 || c2 > MAX_DIM ||
             c1 != r2);

    int a[MAX_DIM][MAX_DIM]; /* more portable this way, as variable dimensioning */
    int b[MAX_DIM][MAX_DIM]; /* is not present in all standard editions */
    /* there's no need to have matrix c as we are not doing anything with it. 
     * (see below why)*/

    printf("enter element of 1st matrix:");
    for (i = 0; i < r1; i++) {
        for (j = 0; j < c1; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    printf("\n-----------------");

    printf("enter element of 2nd matrix:");
    for (i = 0; i < r2; i++) {
        for (j = 0; j < c2; j++) {
            scanf("%d", &b[i][j]);
        }
    }
    
    printf("the resultant matrix is:\n");
    for (i = 0; i < r1; i++) {
        for (j = 0; j < c2; j++) {
            int k;
            int cell_value = 0;
            for (k = 0; k < c1 /* or k < r2, both are the same */; k++) {
                    cell_value += a[i][k] * b[k][j];
            }
            /* cell_value is the value of product matrix at [i][j] */
            printf("%d\t", cell_value);
        }
        printf("\n\n"); /* new line for each row */
    }
    return 0;
}

As you see, this last sample doesn't require to have stored the product matrix c , as you can print the elements (which are generated per rows, then per columns) as they are calculated.如您所见,最后一个示例不需要存储产品矩阵c ,因为您可以在计算元素时打印元素(按行生成,然后按列生成)。

#include<stdio.h>
#include<stdlib.h>
int main(){
    int r1,c1,r2,c2;
   
    int i,j;
    printf("enter row1 and col1:\n");
    scanf("%d%d",&r1,&c1);
    printf("enter row2 and col2:\n");
    scanf("%d%d",&r2,&c2);
     int a[r1][c1];
    int b[r2][c2];
    int c[r1][c2];
    if(c1==r2){
        printf("enter element of 1st matrix:");
        for(i=0;i<r1;i++){
            for(j=0;j<c1;j++){
                scanf("%d",&a[i][j]);
            }
        }
        printf("\n-----------------");
        printf("enter element of 2st matrix:");
        for(i=0;i<r2;i++){
            for(j=0;j<c2;j++){
                scanf("%d",&b[i][j]);
            }
    }
    
    printf("the resultant matrix is:\n");
    for(i=0;i<r1;i++){
        
        for(j=0;j<c2;j++){
            c[i][j]=0;
            for(int k=0;k<c1;k++)    
              {    
           c[i][j]+=a[i][k]*b[k][j];    
              } 
        }
    }
    for(i=0;i<r1;i++){
        for(j=0;j<c2;j++){
            printf("%d\t",c[i][j]);
        }
        printf("\n\n");
    }
    
    
}
return 0;
    
    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM