目录
一、前言
矩阵:在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合。只有当第一个矩阵(左矩阵)的列数等于第二矩阵(右矩阵)的行数时,两矩阵才能相乘。例如:矩阵 A(n×m) 和 B(m×k) 相乘,得到矩阵C(n×k)。
二、题目
如题:编写一个函数实现矩阵A (2行3列)与 矩阵B相乘(3行2列),乘积放在C数组中。在主函数中输入相乘的两数组,并输出结果。
1、题目分析:
题中要求用函数实现矩阵AB的乘积,很明显题目给的两矩阵是可乘的,但是在程序中我们也不能少了判断矩阵是否可乘的步骤。根据题目我们需要使用三个数组来作为运算的矩阵的空间,根据算法实现矩阵的乘积运算...
2、初步构建:
数组、文件、结构体、stdIO、指针
3、预期流程:
运行程序--->输入矩阵的维--->判断是否可乘--->计算--->输出(1、到本地文件 2、到控制台)--->程序结束
三、结构
1、程序组成
main.c>各函数的调用
matrix_fun.h>有关矩阵函数的声明
matrix_fun.c>有关矩阵函数的定义
2、数据存储
typedef struct //定义一个矩阵的结构体
{
int matrix[MAX][MAX]; //结构体中的3个成员变量
int matr_row; //数组的行
int matr_col; //数组的列
}MATRIX; //结构体的成员
3、函数声明
struct MATRIX* Matrix_multiplication(MATRIX* object1, MATRIX* object2); //矩阵的乘法
void Get_Matrix(MATRIX* object1, MATRIX* object2); //获取矩阵的值
void Out_Matrix_toConsole(MATRIX* object); //将一个矩阵输出到控制台
void Out_Matrix_toFile(MATRIX* object, const char* filename); //将一个矩阵输出到文件下
4、运行结构
运行程序--->输入矩阵的维--->判断是否可乘--->计算--->输出(1、到本地文件 2、到控制台)--->程序结束
三、主要程序设计
1、矩阵乘法实现的函数解析:
如图:假设矩阵A(ixj)B(ixj)明显AB可乘,设结果为矩阵C,那么矩阵C的行号为A矩阵的行号,列号为B矩阵的列号。图中能得到C11的值为A11*B11+A12*B21+A13*B31+....+A1j*Bi1。
那么就能得到一个通式:A[][]*B[][]。 就是程序中的(object1->matrix[i][n]) * (object2->matrix[n][j]);
在 A[ i ][ n ]*B[ n ][ j ] 每计算一个值 n 都会从0--->n 然后求和 (其中n的最大值为A的列数或者B的行数),然后就是B矩阵的列数加1,在就算一组值,最后矩阵A的行数加一。容易看出上述过程可由三个循环嵌套完成。
/*乘法运算*/
for (int i = 0; i < theResult->matr_row; i++)【1】
{
for (int j = 0; j < theResult->matr_col; j++) 【2】
{
for (int n = 0; n < object1->matr_col; n++) 【3】
{
temp += (object1->matrix[i][n]) * (object2->matrix[n][j]); 【4】
}
theResult->matrix[i][j] = temp; 【5】
temp = 0; 【6】
}
}
其中外面两层循【1】【2】同时可以遍历C(theResult->matrix[i][j])矩阵,当最里面的循环【3】结束时,说明完成了一个矩阵C的值的计算,这时就可以将所计算出的值存入C(theResult->matrix[i][j])中。这样就可以完成多维(可乘的)矩阵相乘。
函数源码:
/*
@函数作用:计算两个矩阵的乘法
@参数:MATRIX* object1, MATRIX* object2,分别是要计算的矩阵结构体指针对象
@返回值:struct MATRIX*re 返回一个计算后的矩阵结构体指针对象
*/
struct MATRIX* Matrix_multiplication(MATRIX* object1, MATRIX* object2)
{
MATRIX* theResult = (MATRIX*)malloc(sizeof(MATRIX)); //申请空间
theResult->matr_row = object1->matr_row; //保存结果的行
theResult->matr_col = object2->matr_col; //保存结果的列
int temp = 0; //tenp为保存每一个点的值
if (object1->matr_col == object2->matr_row) //判断是否可以乘
{
//如果可乘,提示信息
printf("两个矩阵可乘!\n");
/*乘法运算*/
for (int i = 0; i < theResult->matr_row; i++)
{
for (int j = 0; j < theResult->matr_col; j++)
{
for (int n = 0; n < object1->matr_col; n++)
{
temp += (object1->matrix[i][n]) * (object2->matrix[n][j]);
}
theResult->matrix[i][j] = temp;
temp = 0;
}
}
}
else //如果不可乘,返回一个nullptr,方便主函数中判断
{
printf("两个矩阵不可乘!请重新输入!\n");
theResult = NULL;
}
return theResult;
}
2、文件操作函数
/*
@函数作用:输出一个矩阵到txt文件中
@参数:MATRIX* object 是要输出的矩阵结构体指针对象,const char* filename 输出到的文件名
@返回值:void
*/
void Out_Matrix_toFile(MATRIX* object, const char* filename)
{
if (object)
{
FILE* file; //文件处理的结构体,定义一个文件处理的结构体指针对象
file = fopen(filename, "w+"); //使用fopen函数打开指定文件名的文件
if (file) //若打开成功,fopen返回非空指针
{
printf("成功打开文件:%s\n", filename); //控制台提示打开成功
fputs("两个矩阵相乘的结果为:\n", file); //fputs()向file流中写入字符串
/*将计算结果输出到file流中*/
for (int i = 0; i < object->matr_row; i++)
{
for (int j = 0; j < object->matr_col; j++)
fprintf(file, "%d\t", object->matrix[i][j]); //向file流中格式化输出
fprintf(file, "\n"); //换行
}
fclose(file); //关闭文件流
}
else //打开失败fopen返回空指针
{
printf("打开%s失败\n", filename);
}
free(file); //释放file流
}
else
printf("计算结果为空!");
}
文件的基本操作---略
【其他函数---读者自行理解】
四、源码
matrix_fun.h中:
/*
@C语言课程设计源代码
@功能;计算矩阵的乘法,并且输出到控制台或者文件中
@作者:机设21-6 孔*江
@日期:2022/06/24
*/
#ifndef _MATRIX_FUN_H_
#define _MATRIX_FUN_H_
/*头文件*/
#include <stdio.h>
#include <stdlib.h>
//宏定义 数组的长度
#define MAX 1024
//定义一个矩阵的结构体
typedef struct
{
int matrix[MAX][MAX];//结构体中的3个成员变量
int matr_row; //数组的行
int matr_col; //数组的列
}MATRIX; //结构体的成员
//矩阵的乘法
struct MATRIX* Matrix_multiplication(MATRIX* object1, MATRIX* object2);
//获取矩阵的值
void Get_Matrix(MATRIX* object1, MATRIX* object2);
//将一个矩阵输出到控制台
void Out_Matrix_toConsole(MATRIX* object);
//将一个矩阵输出到文件下
void Out_Matrix_toFile(MATRIX* object, const char* filename);
#endif //_MATRIX_FUN_H_
matrix_fun.c中:
#include "matrix_func.h"
/*
@函数作用:从键盘获取矩阵的值
@参数:MATRIX* object1, MATRIX* object2,分别是要输入到的的矩阵结构体指针对象
@返回值:void
*/
void Get_Matrix(MATRIX* object1, MATRIX* object2)
{
printf("请输入第一矩阵的行数与列数(以空格分隔!):"); //提示信息打印
scanf("%d%d", &(object1->matr_row), &(object1->matr_col)); //读取到结构体object1中
/*数组循环读入*/
for (int i = 0; i < object1->matr_row; i++)
for (int j = 0; j < object1->matr_col; j++)
scanf("%d", &(object1->matrix[i][j]));
printf("请输入第二矩阵的行数与列数(以空格分隔!):"); //提示信息打印
scanf("%d%d", &(object2->matr_row), &(object2->matr_col)); //读取到结构体object2中
/*数组循环读入*/
for (int i = 0; i < object2->matr_row; i++)
for (int j = 0; j < object2->matr_col; j++)
scanf("%d", &(object2->matrix[i][j]));
/*
MATRIX* object1, MATRIX* object2分别指向两个结构体,通过传入这两个的结构体指针
改变两个结构体指针指向的结构体成员的值。
*/
}
/*
@函数作用:计算两个矩阵的乘法
@参数:MATRIX* object1, MATRIX* object2,分别是要计算的矩阵结构体指针对象
@返回值:struct MATRIX*re 返回一个计算后的矩阵结构体指针对象
*/
struct MATRIX* Matrix_multiplication(MATRIX* object1, MATRIX* object2)
{
MATRIX* theResult = (MATRIX*)malloc(sizeof(MATRIX)); //申请空间
theResult->matr_row = object1->matr_row; //保存结果的行
theResult->matr_col = object2->matr_col; //保存结果的列
int temp = 0; //tenp为保存每一个点的值
if (object1->matr_col == object2->matr_row) //判断是否可以乘
{
//如果可乘,提示信息
printf("两个矩阵可乘!\n");
/*乘法运算*/
for (int i = 0; i < theResult->matr_row; i++)
{
for (int j = 0; j < theResult->matr_col; j++)
{
for (int n = 0; n < object1->matr_col; n++)
{
temp += (object1->matrix[i][n]) * (object2->matrix[n][j]);
}
theResult->matrix[i][j] = temp;
temp = 0;
}
}
}
else //如果不可乘,返回一个nullptr,方便主函数中判断
{
printf("两个矩阵不可乘!请重新输入!\n");
theResult = NULL;
}
return theResult;
}
/*
@函数作用:输出一个矩阵到控制台
@参数:MATRIX* object 是要输出的矩阵结构体指针对象
@返回值:void
*/
void Out_Matrix_toConsole(MATRIX* object)
{
if (object)
{
printf("矩阵1乘矩阵2的结果为:\n");
/*循环访问数组的值,并且输出*/
for (int i = 0; i < object->matr_row; i++)
{
for (int j = 0; j < object->matr_col; j++)
printf("%d\t", object->matrix[i][j]);
printf("\n");
}
}
else
printf("计算结果为空!");
}
/*
@函数作用:输出一个矩阵到txt文件中
@参数:MATRIX* object 是要输出的矩阵结构体指针对象,const char* filename 输出到的文件名
@返回值:void
*/
void Out_Matrix_toFile(MATRIX* object, const char* filename)
{
if (object)
{
FILE* file; //文件处理的结构体,定义一个文件处理的结构体指针对象
file = fopen(filename, "w+"); //使用fopen函数打开指定文件名的文件
if (file) //若打开成功,fopen返回非空指针
{
printf("成功打开文件:%s\n", filename); //控制台提示打开成功
fputs("两个矩阵相乘的结果为:\n", file); //fputs()向file流中写入字符串
/*将计算结果输出到file流中*/
for (int i = 0; i < object->matr_row; i++)
{
for (int j = 0; j < object->matr_col; j++)
fprintf(file, "%d\t", object->matrix[i][j]); //向file流中格式化输出
fprintf(file, "\n"); //换行
}
fclose(file); //关闭文件流
}
else //打开失败fopen返回空指针
{
printf("打开%s失败\n", filename);
}
free(file); //释放file流
}
else
printf("计算结果为空!");
}
main.c中:
/*头文件*/
#include "matrix_func.h"
int main()
{
MATRIX* matrix1 = (MATRIX*)malloc(sizeof(MATRIX)); //使用malloc给变量申请空间
MATRIX* matrix2 = (MATRIX*)malloc(sizeof(MATRIX)); // 使用malloc给变量申请空间
/*调用输入函数,将矩阵的值从键盘上输入*/
Get_Matrix(matrix1, matrix2); //传入指针,用户从键盘输入矩阵
/*计算矩阵的乘,声明一个结构体指针存放数据*/
MATRIX* theResult = Matrix_multiplication(matrix1, matrix2);//调用矩阵乘函数
/*输出到“./Matrix_result.txt文件下”*/
Out_Matrix_toFile(theResult, "./Matrix_result.txt");
/*将计算结构输出到控制台*/
Out_Matrix_toConsole(theResult);
/*释放相关空间*/
free(theResult);
free(matrix1);
free(matrix2);
/*停止*/
system("pause");
return 0;
}
【欢迎指正!!!】