文章目录
- 题目
- 参考答案
- 解题思路
- 错点
- 无函数做法
题目
编写程序计算两个矩阵的乘积,请将以下代码复制到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;
}
更多推荐
编写程序计算两个矩阵的乘积,请将以下代码复制到codeblocks中,将multiply函数补充完整,程序运行正确后将所有代码(包括题目中给出的代码)复制到答题
发布评论