level 5
下面是乘法的代码:
#include <stdio.h>
struct mtx{//构造矩阵结构体
int x;
int y;
float dat[101];
}mx0,mx1;
void prtfmtx(struct mtx mx){//格式化输出矩阵
float *tp=mx.dat;
int tmp=mx.x*mx.y;
for(int a=0;a<tmp;a++){
printf("%.1f",*tp++);
if((a+1)%mx.y==0){
printf("\n");
}else{
printf(",");
}
};
}
struct mtx scfmtx(char name){//格式化输入矩阵
struct mtx mx;
printf("行列式%c :\n",name);
printf("输入行数:");
scanf("%d",&mx.x);
printf("输入列数:");
scanf("%d",&mx.y);
printf("输入数据:\n");
int a,tmp=mx.x*mx.y;
for(a=0;a<tmp;a++){
scanf("%f",&mx.dat[a]);
};
printf("行列式%c :\n",name);
prtfmtx(mx);//传入变量x,y,a[0],a[1]...等等,而非结构体mx这就是C的特点,传入数量,而非变量.如需改变被传入数据,可采用返回值
return mx;
}
void init(){
printf("矩阵乘法(最多10行10列)\n");
mx0=scfmtx('M');
//printf("mx0.y=%d...\n",mx0.y);
mx1=scfmtx('N');
//printf("mx1.y=%d...\n",mx1.y);
if(mx0.y!=mx1.x){
printf(" M 的列数必须等于 N 的行数");
}
}
struct mtx mxmtp(){//实现mx0*mx1
struct mtx mx;
float tmpdt[11][11];
int tmp=mx1.x*mx1.y,mtp=0;
for(int a=0;a<mx1.x;a++){//将mx1转置
for(int b=0;b<mx1.y;b++){
tmpdt[b][a]=mx1.dat[mtp++];
}
}
float s=0,*sp=mx0.dat,*tp;
mtp=0;
for(int a=0;a<mx0.x;a++){
for(int b=0;b<mx1.y;b++){
tp=sp;
for(int c=0;c<mx0.y;c++){//mx0每行乘mx1各行
s+=tmpdt[b][c]*(*sp++);
}
mx.dat[mtp]=s;
s=0;mtp++;
sp=tp;
}
sp+=mx0.y;
}
mx.x=mx0.x;
mx.y=mx1.y;
return mx;
}
void main(void) {
init();
printf("\n单击回车键继续");
getchar();
getchar();
printf("\n结果为:\n");
prtfmtx(mxmtp());
}
2019年02月08日 00点02分
2
level 5
乘法程序是第一个写的,有一些不足,主要是为了美观强行让浮点数保留1位小数,如果需要大家可以去格式化输出那一块把printf里"%"和"f"之间的
".1"去掉
2019年02月08日 00点02分
3
level 5
最最重要的,乘法计算的是M×N,也就是程序里的mx0*mx1
2019年02月08日 00点02分
4
level 5
文件名:mtx_sourse.h
#include<stdio.h>
//行
#define row 4
//列
#define col 4
//构造矩阵结构体
struct mx{int i;int j;float dat[row][col];};
struct mx mtx0=
{row,col,{
1,2,3,4,
0,5,6,7,
0,0,8,9,
0,0,0,10
}};
void prtfmtx(struct mx mtx){//格式化输出矩阵
for(int a=0;a<mtx.i;a++)
{
for(int b=0;b<mtx.j;b++)
{
if(mtx.dat[a][b]<0)
printf("%f ",mtx.dat[a][b]);
else
printf(" %f ",mtx.dat[a][b]);
}
printf("\n");
}
}
2019年02月08日 02点02分
8
level 5
文件名:mtx_adjoint.h
#include"mtx_alg_cmp.h"
struct mx mtx_adj(struct mx mtx)//伴随矩阵
{
struct mx mtx1=mtx;
for(int a=0;a<mtx.i;a++)
{
for(int b=0;b<mtx.j;b++)
{
mtx1.dat[b][a]=mtx_a_c(mtx,a,b);
}
}
return mtx1;
}
struct mx mtx_inverse(struct mx mtx)//逆矩阵
{
float det=mtxdet(mtx);
if(det==0)
return;
struct mx mtx1=mtx;
for(int a=0;a<mtx.i;a++)
{
for(int b=0;b<mtx.j;b++)
{
mtx1.dat[b][a]=mtx_a_c(mtx,a,b)/det;
}
}
return mtx1;
}
2019年02月08日 02点02分
10
level 5
文件名:mtx_alg_cmp.h
/*
|
j|
□□■□□ ①
□□■□□
i__■■■■■________
□□■□□
□□■□□
||
②|| ③
||
*/
float mtx_a_c(struct mx mtx,int i,int j)//求代数余子式
{
for(int a=i+1;a<mtx.i;a++)//①
{
for(int b=0;b<j;b++)
{
mtx.dat[a-1][b]=mtx.dat[a][b];
}
}
for(int a=0;a<i;a++)//②
{
for(int b=j+1;b<mtx.j;b++)
{
mtx.dat[a][b-1]=mtx.dat[a][b];
}
}
for(int a=i+1;a<mtx.i;a++)//③
{
for(int b=j+1;b<mtx.j;b++)
{
mtx.dat[a-1][b-1]=mtx.dat[a][b];
}
}
mtx.i-=1;
mtx.j-=1;
float t=mtxdet(mtx);
if(t==0)
return 0;
else if((i+j)%2)
return -t;
else
return t;
}
2019年02月08日 02点02分
11
level 5
文件名:mtx_det.h
#include"mtx_source.h"
float mtxdet(struct mx mtx)
{
short int a=0,b=0,tmpa,exchgflag=0;
//a为行,b为列,tmpa暂存上次的a,exchgflag表示行交换次数
/*↓↓↓化上三角行列式↓↓↓*/
for(;b<mtx.j;b++)//从第零列开始
{
/*↓↓↓检查某列某行是否为零↓↓↓*/
int tmp=a;
if(mtx.dat[a][b]!=0);//若不为零则作罢
else
{
while(a+1<mtx.i)//开始行交换
{
a+=1;
if(mtx.dat[a][b]!=0)
{
/*↓↓↓从某列开始交换两行↓↓↓*/
float tp[row];
for(int z=b;z<mtx.j;z++)
tp[z]=mtx.dat[tmp][z];
for(int z=b;z<mtx.j;z++)
mtx.dat[tmp][z]=mtx.dat[a][z];
for(int z=b;z<mtx.j;z++)
mtx.dat[a][z]=tp[z];
/*↑↑↑从某列开始交换两行↑↑↑*/
exchgflag+=1;//交换两行,符号改变,次数加1
break;
}
}
}
/*↑↑↑检查某列某行是否为零↑↑↑*/
a+=1;
tmpa=a;
for(;a<mtx.i;a++)//行
{
if(mtx.dat[a][b]!=0)
{
/*↓↓↓按化行阶梯形矩阵的方法消去每行第一列↓↓↓*/
float t=mtx.dat[a][b]/mtx.dat[b][b];
for(int z=b;z<mtx.j;z++)
mtx.dat[a][z]-=mtx.dat[b][z]*t;
/*↑↑↑按化行阶梯形矩阵的方法消去每行第一列↑↑↑*/
}else{}
}
a=tmpa;
}/*↑↑↑化上三角行列式↑↑↑*/
//↓↓↓主对角线元素相乘
float tmp=1;
for(a=0;a<mtx.i;a++)
{
tmp*=mtx.dat[a][a];
//printf("%f\n",mtx.dat[a][a]);
}
//↑↑↑
//输出
if(tmp==0)
return 0;
else if(exchgflag%2)
return -tmp;
else
return tmp;
}
2019年02月08日 02点02分
12
level 5
文件名:mtx.c
#include"mtx_adjoint.h"
void main()
{
printf("原矩阵:\n");
prtfmtx(mtx0);
printf("\n");
printf("其行列式的值:\n");
float det=mtxdet(mtx0);
printf("%f\n",det);
printf("\n");
printf("伴随矩阵:\n");
prtfmtx(mtx_adj(mtx0));
printf("\n");
printf("逆矩阵:\n");
if(det==0)
printf(" 不可逆\n");
else
prtfmtx(mtx_inverse(mtx0));
}
2019年02月08日 02点02分
13
level 5
订正:
mtx_alg_cmp.h需要#include"mtx_det.h"
2019年02月08日 03点02分
15