在 C 语言中相乘两个矩阵

CCBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,你将学习如何在C语言中对两个矩阵进行乘法运算。本实验涵盖以下步骤:

读取维度和元素:你将学习如何从用户输入中读取两个矩阵的维度和元素。此步骤可确保矩阵适合进行乘法运算。

按行乘列:你将实现矩阵乘法算法,其中乘积矩阵的每个元素通过将输入矩阵的相应行和列相乘来计算。

打印乘积矩阵:最后,你将显示所得的乘积矩阵。

完成本实验后,你将对C语言中的矩阵乘法有深入的理解,并能够将其应用于各种应用程序。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("C")) -.-> c/ControlFlowGroup(["Control Flow"]) c(("C")) -.-> c/CompoundTypesGroup(["Compound Types"]) c(("C")) -.-> c/FunctionsGroup(["Functions"]) c(("C")) -.-> c/UserInteractionGroup(["User Interaction"]) c/ControlFlowGroup -.-> c/for_loop("For Loop") c/CompoundTypesGroup -.-> c/arrays("Arrays") c/FunctionsGroup -.-> c/function_parameters("Function Parameters") c/UserInteractionGroup -.-> c/user_input("User Input") c/UserInteractionGroup -.-> c/output("Output") subgraph Lab Skills c/for_loop -.-> lab-435191{{"在 C 语言中相乘两个矩阵"}} c/arrays -.-> lab-435191{{"在 C 语言中相乘两个矩阵"}} c/function_parameters -.-> lab-435191{{"在 C 语言中相乘两个矩阵"}} c/user_input -.-> lab-435191{{"在 C 语言中相乘两个矩阵"}} c/output -.-> lab-435191{{"在 C 语言中相乘两个矩阵"}} end

读取维度和元素

在这一步中,你将学习如何在C语言中读取用于矩阵乘法的矩阵维度和元素。我们将创建一个程序,允许用户输入两个矩阵的大小和值。

首先,为我们的矩阵乘法程序创建一个新的C文件:

cd ~/project
nano matrix_multiply.c

现在,添加以下代码来读取矩阵维度:

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;

    // 读取第一个矩阵的维度
    printf("输入第一个矩阵的维度(行数 列数): ");
    scanf("%d %d", &rows1, &cols1);

    // 读取第二个矩阵的维度
    printf("输入第二个矩阵的维度(行数 列数): ");
    scanf("%d %d", &rows2, &cols2);

    // 检查矩阵是否可以相乘
    if (cols1!= rows2) {
        printf("矩阵乘法不可能!\n");
        return 1;
    }

    printf("矩阵维度对于乘法是有效的。\n");

    return 0;
}

编译并运行程序:

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

示例输出:

输入第一个矩阵的维度(行数 列数): 2 3
输入第二个矩阵的维度(行数 列数): 3 2
矩阵维度对于乘法是有效的。

让我们来分析一下这段代码:

  • 我们将 MAX_SIZE 定义为100以限制矩阵维度
  • scanf() 用于从用户输入中读取矩阵维度
  • 我们通过比较第一个矩阵的列数和第二个矩阵的行数来检查矩阵乘法是否可行
  • 如果维度不兼容,程序会打印错误消息

现在,让我们修改代码以读取矩阵元素:

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];

    // 读取第一个矩阵的维度
    printf("输入第一个矩阵的维度(行数 列数): ");
    scanf("%d %d", &rows1, &cols1);

    // 读取第二个矩阵的维度
    printf("输入第二个矩阵的维度(行数 列数): ");
    scanf("%d %d", &rows2, &cols2);

    // 检查矩阵是否可以相乘
    if (cols1!= rows2) {
        printf("矩阵乘法不可能!\n");
        return 1;
    }

    // 读取第一个矩阵的元素
    printf("输入第一个矩阵的元素:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("输入元素 [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // 读取第二个矩阵的元素
    printf("输入第二个矩阵的元素:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("输入元素 [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    printf("矩阵已成功读取。\n");

    return 0;
}

编译并运行程序:

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

示例输出:

输入第一个矩阵的维度(行数 列数): 2 3
输入第二个矩阵的维度(行数 列数): 3 2
输入第一个矩阵的元素:
输入元素 [0][0]: 1
输入元素 [0][1]: 2
输入元素 [0][2]: 3
输入元素 [1][0]: 4
输入元素 [1][1]: 5
输入元素 [1][2]: 6
输入第二个矩阵的元素:
输入元素 [0][0]: 7
输入元素 [0][1]: 8
输入元素 [1][0]: 9
输入元素 [1][1]: 10
输入元素 [2][0]: 11
输入元素 [2][1]: 12
矩阵已成功读取。

按行乘列

在这一步中,你将学习如何通过将第一个矩阵的行与第二个矩阵的列相乘来执行矩阵乘法。我们将基于之前的代码来实现矩阵乘法算法。

更新 matrix_multiply.c 文件以添加矩阵乘法功能:

cd ~/project
nano matrix_multiply.c

用以下实现替换之前的代码:

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];
    int result[MAX_SIZE][MAX_SIZE];

    // 读取第一个矩阵的维度
    printf("输入第一个矩阵的维度(行数 列数): ");
    scanf("%d %d", &rows1, &cols1);

    // 读取第二个矩阵的维度
    printf("输入第二个矩阵的维度(行数 列数): ");
    scanf("%d %d", &rows2, &cols2);

    // 检查矩阵是否可以相乘
    if (cols1!= rows2) {
        printf("矩阵乘法不可能!\n");
        return 1;
    }

    // 读取第一个矩阵的元素
    printf("输入第一个矩阵的元素:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("输入元素 [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // 读取第二个矩阵的元素
    printf("输入第二个矩阵的元素:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("输入元素 [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    // 矩阵相乘
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            result[i][j] = 0;
            for (int k = 0; k < cols1; k++) {
                result[i][j] += matrix1[i][k] * matrix2[k][j];
            }
        }
    }

    // 打印结果矩阵
    printf("\n结果矩阵:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("%d ", result[i][j]);
        }
        printf("\n");
    }

    return 0;
}

编译并运行程序:

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

示例输出:

输入第一个矩阵的维度(行数 列数): 2 3
输入第二个矩阵的维度(行数 列数): 3 2
输入第一个矩阵的元素:
输入元素 [0][0]: 1
输入元素 [0][1]: 2
输入元素 [0][2]: 3
输入元素 [1][0]: 4
输入元素 [1][1]: 5
输入元素 [1][2]: 6
输入第二个矩阵的元素:
输入元素 [0][0]: 7
输入元素 [0][1]: 8
输入元素 [1][0]: 9
输入元素 [1][1]: 10
输入元素 [2][0]: 11
输入元素 [2][1]: 12

结果矩阵:
58 64
139 154

让我们来分析一下矩阵乘法算法:

  • 最外层的两个循环 ij 遍历结果矩阵
  • 内层循环 k 执行第一个矩阵的第 i 行与第二个矩阵的第 j 列的点积
  • result[i][j] 通过将对应元素的乘积相加来计算
  • 嵌套循环确保结果矩阵的每个元素都被正确计算

关于矩阵乘法的要点:

  • 第一个矩阵的列数必须等于第二个矩阵的行数
  • 所得矩阵的维度将是(第一个矩阵的行数)×(第二个矩阵的列数)

打印乘积矩阵

在这最后一步中,我们将通过添加更强大的打印功能和错误处理来增强我们的矩阵乘法程序。我们将创建函数来打印矩阵,并改善整体用户体验。

使用以下改进后的实现更新 matrix_multiply.c 文件:

cd ~/project
nano matrix_multiply.c

用这个完整版本替换之前的代码:

#include <stdio.h>

#define MAX_SIZE 100

// 函数:打印矩阵
void printMatrix(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols, const char* matrixName) {
    printf("\n%s矩阵:\n", matrixName);
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%5d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];
    int result[MAX_SIZE][MAX_SIZE];

    // 读取第一个矩阵的维度
    printf("输入第一个矩阵的维度(行数 列数): ");
    scanf("%d %d", &rows1, &cols1);

    // 读取第二个矩阵的维度
    printf("输入第二个矩阵的维度(行数 列数): ");
    scanf("%d %d", &rows2, &cols2);

    // 检查矩阵是否可以相乘
    if (cols1!= rows2) {
        printf("矩阵乘法不可能!\n");
        printf("第一个矩阵的列数(%d)必须等于第二个矩阵的行数(%d)。\n", cols1, rows2);
        return 1;
    }

    // 读取第一个矩阵的元素
    printf("输入第一个矩阵的元素:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("输入元素 [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // 读取第二个矩阵的元素
    printf("输入第二个矩阵的元素:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("输入元素 [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    // 打印输入矩阵
    printMatrix(matrix1, rows1, cols1, "第一个输入");
    printMatrix(matrix2, rows2, cols2, "第二个输入");

    // 矩阵相乘
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            result[i][j] = 0;
            for (int k = 0; k < cols1; k++) {
                result[i][j] += matrix1[i][k] * matrix2[k][j];
            }
        }
    }

    // 打印结果矩阵
    printMatrix(result, rows1, cols2, "乘积");

    return 0;
}

编译并运行程序:

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

示例输出:

输入第一个矩阵的维度(行数 列数): 2 3
输入第二个矩阵的维度(行数 列数): 3 2
输入第一个矩阵的元素:
输入元素 [0][0]: 1
输入元素 [0][1]: 2
输入元素 [0][2]: 3
输入元素 [1][0]: 4
输入元素 [1][1]: 5
输入元素 [1][2]: 6
输入第二个矩阵的元素:
输入元素 [0][0]: 7
输入元素 [0][1]: 8
输入元素 [1][0]: 9
输入元素 [1][1]: 10
输入元素 [2][0]: 11
输入元素 [2][1]: 12

第一个输入矩阵:
    1     2     3
    4     5     6

第二个输入矩阵:
    7     8
    9    10
   11    12

乘积矩阵:
   58    64
  139   154

此版本的主要改进:

  • 创建了 printMatrix() 函数以一致的格式打印矩阵
  • 为矩阵乘法兼容性添加了更具描述性的错误消息
  • 在显示乘积矩阵之前打印输入矩阵
  • 使用 %5d 进行对齐的矩阵打印
  • 提供了清晰、可读的输出格式

打印函数的解释:

  • printMatrix() 将矩阵、其维度和一个名称作为参数
  • 使用嵌套循环打印每个元素
  • %5d 格式说明符确保每个数字占用5个空格进行对齐
  • 每行之后添加换行符以提高可读性

总结

在本实验中,你将学习如何读取矩阵的维度和元素,然后在C语言中执行矩阵乘法。首先,你将学习如何读取两个矩阵的维度,并检查它们是否适合进行乘法运算。然后,你将学习如何读取两个矩阵的元素并将它们存储在二维数组中。最后,你将学习如何执行实际的矩阵乘法并打印所得的乘积矩阵。