admin管理员组

文章数量:1794759

编写程序计算两个矩阵的乘积,请将以下代码复制到codeblocks中,将multiply函数补充完整,程序运行正确后将所有代码(包括题目中给出的代码)复制到答题区内运行并提交。C语言矩阵相乘

编写程序计算两个矩阵的乘积,请将以下代码复制到codeblocks中,将multiply函数补充完整,程序运行正确后将所有代码(包括题目中给出的代码)复制到答题区内运行并提交。C语言矩阵相乘

文章目录
    • 题目
    • 参考答案
    • 解题思路
    • 错点
    • 无函数做法

题目

编写程序计算两个矩阵的乘积,请将以下代码复制到codeblocks中,将multiply函数补充完整,程序运行正确后将所有代码(包括题目中给出的代码)复制到答题区内运行并提交。 #include <stdio.h> #define M 3 #define S 4 #define N 2

void multiply(int A[M][S], int B[S][N], int C[M][N]) {

}

int main() { int i, j; int A[M][S], B[S][N], C[M][N]; printf(“Please input A:\\n”); for (i = 0; i < M; i ++) for (j = 0; j < S; j ++) scanf("%d", &A[i][j]); printf(“Please input B:\\n”); for (i = 0; i < S; i ++) for (j = 0; j < N; j ++) scanf("%d", &B[i][j]); multiply(A,B,C); printf(“C=\\n”); for (i = 0; i < M; i ++){ for (j = 0; j < N; j ++) printf("%d “, C[i][j]); printf(”\\n"); } return 0; } 程序运行示例: Please input A: 1 2 3 4 5 6 7 8 4 7 9 2 Please input B: 2 6 4 8 4 6 3 9 C= 34 76 86 192 78 152

参考答案 #include <stdio.h> #define M 3 #define S 4 #define N 2 void multiply(int A[M][S], int B[S][N], int C[M][N]) { int i, j, k; for (i = 0; i < M; i++) //用于控制C和A的行标 { for (j = 0; j < N; j++) //用于控制C和B的列标 { for (k = 0; k < S; k++) //用于控制A的列标和B的行标 { C[i][j] += A[i][k] * B[k][j]; } } } } int main() { int i, j; int A[M][S], B[S][N], C[M][N] = {0}; //必须对C数组进行初始化 printf("Please input A:\\n"); for (i = 0; i < M; i++) for (j = 0; j < S; j++) //输入A数组 scanf_s("%d", &A[i][j]); printf("Please input B:\\n"); for (i = 0; i < S; i++) for (j = 0; j < N; j++) //输入B数组 scanf_s("%d", &B[i][j]); multiply(A, B, C); //调用函数 printf("C=\\n"); for (i = 0; i < M; i++) { for (j = 0; j < N; j++) printf("%d ", C[i][j]); //以矩阵的形式输出C数组 printf("\\n"); } return 0; } 解题思路

只需要写出计算C数组的前三个式子就可发现规律:

  • C[0][0]= A[0][0] * B[0][0] + A[0][1] * B[1][0] + A[0][2] * B[2][0] + A[0][3] * B[3][0]
  • C[0][1]= A[0][0] * B[0][1] + A[0][1] * B[1][1] + A[0][2] * B[2][1] + A[0][3] * B[3][1]
  • C[1][0]= A[1][0] * B[0][0] + A[1][1] * B[1][0] + A[1][2] * B[2][0] + A[1][3] * B[3][0] 则可以发现:C和A的行标同时变化,C和B的列标同时变化,A的列标和B的行标同时变化。 在计算过程中:最先进行循环的是A列标和B行标的变化,所以该循环放在最里面,而外层的两个循环可用于控制C的行列标运动。 (上述为先算C数组每一行的做法,也可以改变循环的过程,先算第一列,再算第二列)
错点

在写这道题的过程中,我遇到的问题有两个:

  • 在编写函数时,若未找对规律,容易发生数组下标越界的问题,虽然会有数值写入C数组中,但是数值错误,且会有运行错误,如下:
  • void multiply(int A[M][S], int B[S][N], int C[M][N]) { int i, j, k; for (i = 0; i < S; i++) { for (j = 0; j < N; j++) { for (k = 0; k < M; k++) { C[i][j] = A[i][k] + B[k][j]; } } } }

    如上,存在逻辑错误,会将C[M][N]以C[S][N]的形式来计算,而A和B也会有同样的错误,在VS2019中会有变量堆栈被破坏之类的错误。

    Run-Time Check Failure #2 - Stack around the variable 'B' was corrupted.
  • 数组C未初始化引起的答案错误:
  • C= -858993426 -858993384 -858993374 -858993268 //出现的值全部为随机值 -858993382 -858993308

    起初会认为是函数的问题,但并非如此。 细节虽小,但很重要!!!

    无函数做法 #include <stdio.h> #define M 3 #define S 4 #define N 2 int main() { int i, j, k; int A[M][S], B[S][N], C[M][N] = {0}; //初始化很重要 printf("Please input A:\\n"); for (i = 0; i < M; i++) for (j = 0; j < S; j++) scanf_s("%d", &A[i][j]); printf("Please input B:\\n"); for (i = 0; i < S; i++) for (j = 0; j < N; j++) scanf_s("%d", &B[i][j]); for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { for (k = 0; k < S; k++) { C[i][j] += A[i][k] * B[k][j]; } } } printf("C=\\n"); for (i = 0; i < M; i++) { for (j = 0; j < N; j++) printf("%d ", C[i][j]); printf("\\n"); } return 0; }

    本文标签: 代码矩阵乘积程序后将