关于C中2个矩阵之间的乘积的函数

Function about the product between 2 Matrix in C

我在 运行 我的代码中遇到问题,因为即使我尝试了不同的解决方案,我创建的用于在两个矩阵之间进行乘法运算的函数仍然无法正常工作,可能我遗漏了一些关于指针的重要信息在函数中。

因为代码在函数本身的调用附近停止 运行,如果这个 post 没有完全正确完成或编写,请原谅,但这是我第一次 post网站。

这是我的代码,希望有人能帮助我。

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

#define MAXR 50
#define MAXC 50

void printmatrix(int **matrix, int r, int c) {
    int i, j;
    for (i = 0; i < r; i++) {
        printf("\n");
        for (j = 0; j < c; j++) {
            printf("-%d-", matrix[i][j]);
        }
    }
}

void matrixprod(int **matrix3, int matrix1[][MAXC], int matrix2[][MAXC], int r1, int c1, int r2, int c2) {
    int i, h, k;
    h = k = 0;

    matrix3[h][k]=0;
    for (i = 0; i < c1; i++) {
        matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
    }
    k++;
    while (k < c2) {
        matrix3[h][k] = 0;
        for (i = 0; i < c1; i++) {
            matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
        }
        k++;
    }
    while (h < r1) {
        h++;
        k = 0;
        matrix3[h][k] = 0;
        for (i = 0; i < c1; i++) {
            matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
        }
        k++;
        while (k < c2) {
            matrix3[h][k] = 0;
            for (i = 0; i < c1; i++) {
                matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
            }
            k++;
        }
    }
}

int main() {
    int i, j, h, k;
    int r1, r2, c1, c2;
    printf("Inserire la dimensione R delle righe e C delle colonne:\n");
    scanf("%d%d", &r1, &c1);
    int matrix1[r1][c1];
    printf("\n**RIEMPIRE LA MATRICE 1 **\n");
    for (i = 0; i < r1; i++) {
        for (j = 0; j < c1; j++) {
            scanf("%d", &matrix1[i][j]);
        }
    }
    printf("Inserire la dimensione R delle righe e C delle colonne:\n");
    scanf("%d%d", &r2, &c2);
    int matrix2[r2][c2];
    printf("\n**RIEMPIRE LA MATRICE 2 **\n");
    for (i = 0; i < r2; i++) {
        for (j = 0; j < c2; j++) {
            scanf("%d", &matrix2[i][j]);
        }
    }
    int **matrix3;
    matrix3 = malloc(r1 * sizeof(*matrix3));
    for (i = 0; i < r1; i++) {
        matrix3[i] = malloc(c2 * sizeof(*matrix3[i]));
    }
    if (r1 != c2) {
        printf("PROD NON ESEGUIBILE");
        exit(1);
    }
    printf("\n****PROD MATRIX*****\n");
    matrixprod(matrix3, matrix1, matrix2, r1, c1, r2, c2);
    printmatrix(matrix3, r1, c2);
    return 0;
}

实际上有各种各样的问题需要您解决。

首先,在C语言中声明像int a[size]这样的数组时,size必须是常量不能是变量,因为编译器需要在编译时知道它的大小。要声明 int matrix1[r1][c1],您必须使用动态分配或使用 int matrix1[MAXR][MAXC]

其次,将h++放在循环的末尾,否则在最后一次执行循环时h将等于r1。

第三,缩进对于代码的可读性和可维护性非常重要。对于 python 等其他语言,错误的缩进将不起作用。所以适当缩进。

更正代码如下:

#include <stdio.h>
#include <stdlib.h>
#define MAXR 50
#define MAXC 50

void printmatrix(int** matrix, int r, int c) {
    int i, j;
    for (i = 0; i<r; i++) {
        printf("\n");
        for (j = 0; j<c; j++) {
            printf("-%d-", matrix[i][j]);
        }
    }
}

void matrixprod(int** matrix3, int ** matrix1, int ** matrix2, int r1, int c1, int r2, int c2) {
    int i, h, k;
    h = k = 0;
    matrix3[h][k] = 0;
    for (i = 0; i<c1; i++) {
        matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
    }
    k++;
    while (k<c2) {
        matrix3[h][k] = 0;
        for (i = 0; i<c1; i++) {
            matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
        }
        k++;
    }
    while (h<r1) {
        k = 0;
        matrix3[h][k] = 0;
        for (i = 0; i<c1; i++) {
            matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
        }
        k++;
        while (k<c2) {
            matrix3[h][k] = 0;
            for (i = 0; i<c1; i++) {
                matrix3[h][k] += (matrix1[h][i] * matrix2[i][k]);
            }
            k++;
        }

        h++;
    }

}

int main() {
    int i, j, h, k;
    int r1, r2, c1, c2;
    printf("Inserire la dimensione R delle righe e C delle colonne:\n");
    scanf("%d%d", &r1, &c1);
    int ** matrix1 = (int **)malloc(r1 * sizeof(int*));
    printf("\n**RIEMPIRE LA MATRICE 1 **\n");
    for (i = 0; i<r1; i++) {
        matrix1[i] = (int *)malloc(c1 * sizeof(int));
        for (j = 0; j<c1; j++) {
            scanf("%d", &matrix1[i][j]);
        }
    }
    printf("Inserire la dimensione R delle righe e C delle colonne:\n");
    scanf("%d%d", &r2, &c2);
    int ** matrix2 = (int **)malloc(r2 * sizeof(int*));
    printf("\n**RIEMPIRE LA MATRICE 2 **\n");
    for (i = 0; i<r2; i++) {
        matrix2[i] = (int *)malloc(c2 * sizeof(int));
        for (j = 0; j<c2; j++) {
            scanf("%d", &matrix2[i][j]);
        }
    }
    int** matrix3;
    matrix3 = (int **)malloc(r1 * sizeof(int*));
    for (i = 0; i<r1; i++) {
        matrix3[i] = (int *)malloc(c2 * sizeof(int));
    }
    if (r1 != c2) {
        printf("PROD NON ESEGUIBILE");
        exit(1);
    }
    printf("\n****PROD MATRIX*****\n");
    matrixprod(matrix3, matrix1, matrix2, r1, c1, r2, c2);
    printmatrix(matrix3, r1, c2);
    return 0;
}

省略了自由函数。

您的代码中存在多个问题:

  • main 函数中的定义与 matrixprod 函数中的声明之间的二维矩阵大小不一致。您应该将源矩阵 matrix1matrix2 定义为 int matrix1[r2][MAXC];int matrix1[MAXR][MAXC];

  • 您可以简化代码:第一行不需要特殊的外壳,使用经典的 for 循环比 while 循环更不容易出错。

这是修改后的版本:

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

#define MAXR 50
#define MAXC 50

void printmatrix(int **matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf(" %d", matrix[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

void matrixprod(int **matrix3, int matrix1[][MAXC], int matrix2[][MAXC],
                int r1, int c1, int r2, int c2) {
    if (c1 != r2) {
        printf("matrix geometries are incompatible\n");
        return;
    }
    for (int i = 0; i < r1; i++) {
        for (int j = 0; j < c2; j++) {
            int p = 0;
            for (int k = 0; k < c1; k++) {
                 p += matrix1[i][k] * matrix2[k][j];
            }
            matrix3[i][j] = p;
        }
    }
}

int main(void) {
    int r1, r2, c1, c2;
    printf("Inserire la dimensione R delle righe e C delle colonne:\n");
    if (scanf("%d%d", &r1, &c1) != 2 || r1 <= 0 || c1 <= 0 || r1 > MAXR || c1 > MAXC) {
        printf("invalid matrix size\n");
        return 1;
    }
    int matrix1[MAXR][MAXC];
    printf("\n**RIEMPIRE LA MATRICE 1 **\n");
    for (int i = 0; i < r1; i++) {
        for (int j = 0; j < c1; j++) {
            if (scanf("%d", &matrix1[i][j]) != 1)
                return 1;
        }
    }
    printf("Inserire la dimensione R delle righe e C delle colonne:\n");
    if (scanf("%d%d", &r2, &c2) != 2 || r2 <= 0 || c2 <= 0 || r2 > MAXR || c2 > MAXC) {
        printf("invalid matrix size\n");
        return 1;
    }
    int matrix2[MAXR][MAXC];
    printf("\n**RIEMPIRE LA MATRICE 2 **\n");
    for (int i = 0; i < r2; i++) {
        for (int j = 0; j < c2; j++) {
            if (scanf("%d", &matrix2[i][j]) != 1)
                return 1;
        }
    }
    if (c1 != r2) {
        printf("PROD NON ESEGUIBILE");
        exit(1);
    }
    int **matrix3 = malloc(r1 * sizeof(*matrix3));
    if (matrix3 == NULL)
        return 1;
    for (int i = 0; i < r1; i++) {
        matrix3[i] = malloc(c2 * sizeof(*matrix3[i]));
        if (matrix3[i] == NULL)
            return 1;
    }
    printf("\n****PROD MATRIX*****\n");
    matrixprod(matrix3, matrix1, matrix2, r1, c1, r2, c2);
    printmatrix(matrix3, r1, c2);
    return 0;
}

请注意,您可以为所有 3 个操作数分配间接矩阵,从而移除 MAXCMAXR 约束:

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

void free_matrix(int **matrix, int rows) {
    /* free a dynamic matrix */
    if (matrix != NULL) {
        for (int i = 0; i < rows; i++) {
            free(matrix[i]);
        }
        free(matrix);
    }
}

int **new_matrix(int rows, int cols) {
    /* allocate a dynamic matrix initialized to 0 */
    int **matrix = malloc(rows * sizeof(*matrix));
    if (matrix != NULL) {
        for (int i = 0; i < rows; i++) {
            matrix[i] = calloc(cols, sizeof(*matrix[i]));
            if (matrix[i] == NULL) {
                free_matrix(matrix, i);
                return NULL;
            }
        }
    }
    return matrix;
}

int **read_matrix(int *rows, int *cols) {
    int **matrix;
    printf("Inserire la dimensione R delle righe e C delle colonne:\n");
    if (scanf("%d%d", rows, cols) != 2 || *rows <= 0 || *cols <= 0) {
        printf("invalid matrix size\n");
        return NULL;
    }
    matrix = new_matrix(*rows, *cols);
    if (matrix) {
        printf("\n**RIEMPIRE LA MATRICE**\n");
        for (int i = 0; i < *rows; i++) {
            for (int j = 0; j < *cols; j++) {
                if (scanf("%d", &matrix[i][j]) != 1) {
                    free_matrix(matrix, i);
                    return NULL;
                }
            }
        }
    }
    return matrix;
}

void printmatrix(int **matrix, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf(" %d", matrix[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

int **matrixprod(int **matrix1, int **matrix2, int r1, int c1, int r2, int c2) {
    if (c1 != r2) {
        printf("matrix geometries are incompatible\n");
        return NULL;
    }
    int **matrix3 = new_matrix(r1, c2);
    if (matrix3) {
        for (int i = 0; i < r1; i++) {
            for (int j = 0; j < c2; j++) {
                int p = 0;
                for (int k = 0; k < c1; k++) {
                    p += matrix1[i][k] * matrix2[k][j];
                }
                matrix3[i][j] = p;
            }
        }
    }
    return matrix3;
}

int main(void) {
    int r1, r2, c1, c2;
    int **matrix1, **matrix2, **matrix3;
    if (!(matrix1 = read_matrix(&r1, &c1)) || !(matrix2 = read_matrix(&r2, &c2)))
        return 1;
    if (c1 != r2) {
        printf("PROD NON ESEGUIBILE");
        exit(1);
    }
    printf("\n****PROD MATRIX*****\n");
    matrix3 = matrixprod(matrix1, matrix2, r1, c1, r2, c2);
    if (matrix3) {
        printmatrix(matrix3, r1, c2);
        free_matrix(matrix3, r1);
    }
    free_matrix(matrix2, r2);
    free_matrix(matrix1, r1);
    return 0;
}

我也做了这个练习。如果您需要,我可以添加评论。

#include <stdio.h>
#include <stdlib.h>
#define MAXR 50
#define MAXC 50
typedef struct mtrx {
    int **values;
    int rows;   
    int cols;   
} mtrx;

void free_values_memory(mtrx *matrix); 
void error_exit(char *message); 
void allocate_memory_for_values(mtrx *matrix); 
mtrx multiply_mtrxs(mtrx *matrix_1, mtrx *matrix_2); 
void read_mtrx(mtrx *matrix); 
void print_mtrx(mtrx *matrix); 

int main() {
    mtrx matrix_1;
    mtrx matrix_2;

    read_mtrx(&matrix_1);
    read_mtrx(&matrix_2);

    if(matrix_1.cols != matrix_2.rows)
        error_exit("the number of columns of the 1st matrix must equal the number "
        "of rows of the 2nd matrix.");

    mtrx matrix_product = multiply_mtrxs(&matrix_1, &matrix_2);
    print_mtrx(&matrix_product);

    free_values_memory(&matrix_1);
    free_values_memory(&matrix_2);
    free_values_memory(&matrix_product);
    return 0;
}

void error_exit(char *message) {
    printf("3[1;31mInput is incorrect:3[0;0m %s\n", message);
    exit(EXIT_FAILURE);
}

void read_mtrx(mtrx *matrix) {
    if(scanf("%d %d\n", &matrix->rows, &matrix->cols) != 2)
        error_exit("not enough values");
    else if(matrix->rows > MAXR || matrix->cols > MAXC)
        error_exit("the size of matrix too large");

    allocate_memory_for_values(matrix);

    int i, j;
    for(i = 0; i < matrix->rows; i++) {
        for(j = 0; j < matrix->cols; j++) {
            scanf("%d", &matrix->values[i][j]);
        }
    }
}

void allocate_memory_for_values(mtrx *matrix) {
    matrix->values = malloc(matrix->rows * sizeof(matrix->rows));
    int i;
    for(i = 0; i < matrix->rows; i++) {
        matrix->values[i] = malloc(matrix->cols * sizeof(matrix->cols));
    }
}
void free_values_memory(mtrx *matrix) {
    int i;
    for(i = 0; i < matrix->rows; i++) {
        free(matrix->values[i]);
    }
    free(matrix->values);
}

mtrx multiply_mtrxs(mtrx *matrix_1, mtrx *matrix_2) {
    mtrx matrix_product;
    matrix_product.rows = matrix_1->rows;
    matrix_product.cols = matrix_2->cols;
    allocate_memory_for_values(&matrix_product);

    int i, j, k, product;
    for(i = 0; i < matrix_1->rows; i++) {
        for(j = 0; j < matrix_1->cols; j++) {
            for(k = 0; k < matrix_2->cols; k++) {
                product = matrix_1->values[i][j] * matrix_2->values[j][k];
                matrix_product.values[i][k] += product;
            }
        }
    }
    return matrix_product;
}

void print_mtrx(mtrx *matrix) {
    int i, j;
    for(i = 0; i < matrix->rows; i++) {
        for(j = 0; j < matrix->cols; j++) {
            printf("%d ", matrix->values[i][j]);
        }
        puts("");
    }
}

已使用以下输入进行测试:

1 1
2
1 2
2 3
### Answer: ###
4 6
######

2 2
1 2
3 4
2 2
5 6
7 8
### Answer: ###
19 22 
43 50
######

1 3
3 4 2 
3 4
13 9 7 15
8 7 4 6 
6 4 0 3 
### Answer: ###
83 63 37 75
######

2 4
1 2 3 
4 5 6 
3 2
7 8
9 10
11 12
### Answer: ###
58 64 
139 154
######