编制函数实现矩阵运算_第1页
编制函数实现矩阵运算_第2页
编制函数实现矩阵运算_第3页
编制函数实现矩阵运算_第4页
编制函数实现矩阵运算_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

编制函数实现矩阵运算C语言课程设计报告2012年9月1日目录设计目的与要求2总体设计2详细设计2调试分析13设计总结及心得体会16答辩记录16教师意见171.1设计目的:巩固对C语言基本知识与技能的掌握,并且利用所学解决简单的程序设计问题。1.2.1设计要求:任选所给题目之一,也可以自己找难度相当的题目。其中A级题目可以一人完成也可以两人合作完成,B级要求个人单独完成。要对源程序进行注释和分析,并且工整书写程序。1.2.2题目:编制不同的函数实现以下矩阵运算的功能要求矩阵加减;(b)矩阵数乘;(c)矩阵乘法;(d)矩阵转置。2.总体设计2.1开始主函数流程图:开始选择运算类型进行运算并输出结果结束选择运算类型进行运算并输出结果结束转置数乘减法加法转置数乘减法加法乘法乘法是是是否再次运算是否再次运算否否2.2子函数流程图(1)加法、减法、乘法运算函数流程图(2)转置、数乘运算函数流程图开始开始开始开始开辟存放二维数组的空间开辟存放二维数组的空间开辟存放二维数组的空间开辟存放二维数组的空间判断两个矩阵是否可以进行运算判断两个矩阵是否可以进行运算输入矩阵数据并显示输入矩阵数据并显示是是进行运算并显示结果进行运算并显示结果输入矩阵数据并显示输入矩阵数据并显示释放二维数组空间进行运算并显示结果释放二维数组空间进行运算并显示结果释放二维数组空间释放二维数组空间否否结束结束结束结束3.详细设计整个程序由一个主函数和五个子函数组成。主函数中通过调用子函数来完成运算过程,这样使得主函数看起来清晰明了,需要修改时也方便简洁,符合模块化设计的原则。在主函数中定义了两个整型变量ch1和ch2,将ch1的值初始化为1,以保证第一次计算的运行,在每一次计算结束后都会显示“重新运算?”,根据提示输入数字赋值给ch1,从而决定是否执行while循环中的内容。ch2是用来选择运算类型的,主函数源代码如下:#include<stdio.h>#include<stdlib.h>intmain(){ voidcheng();/*函数声明*/ voidadd(); voidjian(); voidshucheng(); voidzhuanzhi(); intch1=1,ch2; while(ch1==1)/*设置循环,在一次运行里可以进行多次运算*/{printf("请选择运算类型\n1:加法\n2:减法\n3:乘法\n4:数乘\n5:转置\n");/*显示选项,选择运算类型*/scanf("%d",&ch2);if(ch2==1)add();/*根据不同的选择,执行相应的函数*/if(ch2==2)jian();if(ch2==3)cheng();if(ch2==4)shucheng();if(ch2==5)zhuanzhi();printf("重新运算?\n1是0否\n");/*显示提示,根据提示输入选项选择是否继续计算,不继续便结束程序*/scanf("%d",&ch1);} return0;}各种运算所对应的函数如下:加法voidadd();减法voidjian();乘法voidcheng();数乘voidshucheng();转置voidzhuanzhi()。每个子函数都没有返回值,都是在子函数内部完成运算,并显示结果。每个子函数都是在一开始的时候询问矩阵的行数以及列数,然后根据显示的提示来输入数字,再将输入的数据赋给各自相应的整型变量。这样子设计是为了根据需要的大小来开辟二维数组空间,而不是从一开始就定义好数组及其大小,如inta[80][80]。根据需要开辟二维数组可以避免浪费原本不必要占用的空间,更具有灵活性,不会将矩阵的行数和列数限制在特定的范围内,如a[80][80]最多只能用来存放80行*80列的方阵,即便将80改成800,也是有所限制的。对于数乘和转置,是单个矩阵的运算,所以不用判断输入的矩阵之间是否可以计算。但是进行加减运算时,两个矩阵之间的行数和列数要都相等才能执行计算,所以需要判断计算的可行性,如果行数和列数之中有一项不相等便不能运算,结束程序;进行乘法运算时,根据线性代数的相关知识,若是矩阵A*B,那么矩阵A的列数就要等于矩阵B的行数,否则不可以计算,同样结束程序,且两个矩阵相乘得出的矩阵的行数与矩阵A相等,列数与矩阵B相等。子函数中,在计算结束之后,用free函数释放之前开辟的二维数组空间。由于用到了malloc函数开辟空间和free函数,所以在开头要加上#include<stdlib.h>。各个子函数源代码如下:voidcheng()/*定义实现矩阵乘法的函数*/{inti=0,j=0,line1=0,row1=0,line2=0,row2=0,n;int**p=NULL;/*p是二重指针,用来存储二维数组(即矩阵)*/int**q=NULL;/*q是二重指针,用来存储二维数组(即矩阵)*/int**result=NULL;/*result是二重指针,用来存储二维数组(即矩阵)*/printf("***(温馨提示:矩阵的乘法要求前一个矩阵的列数等于后一个矩阵的行数)***\n");printf("请输入矩阵1的行数:\n");scanf("%d",&row1);printf("请输入矩阵1的列数:\n");scanf("%d",&line1);p=(int**)malloc(sizeof(int*)*row1);/*将p强制转换为(int**)型的指针,并且根据需要的行数开辟行指针空间*/if(NULL==p){exit(0);}/*如果根据需要开辟的指针为空指针,便结束程序*/for(i=0;i<row1;i++){*(p+i)=(int*)malloc(sizeof(int)*line1);}/*根据需要的列数开辟列指针空间*/if(NULL==*(p+i)){exit(0);}printf("请输入矩阵2的行数:\n");scanf("%d",&row2);printf("请输入矩阵2的列数:\n");scanf("%d",&line2);if(line1!=row2)/*判断两个矩阵是否可以相乘(即第一个矩阵的列数是否等于第二个矩阵的行数*/{ printf("无法相乘!\n"); exit(0);}q=(int**)malloc(sizeof(int*)*row2);if(NULL==q){exit(0);}for(i=0;i<row2;i++){*(q+i)=(int*)malloc(sizeof(int)*line2);}if(NULL==*(q+i)){exit(0);}if(line1==row2)/*若满足两个矩阵可以相乘的条件,便可赋值并执行运算*/{ intline,row;line=line2;row=row1;result=(int**)malloc(sizeof(int*)*row);/*开辟第三个二维数组,用来存放运算结果*/if(NULL==p){exit(0);}for(i=0;i<row;i++){*(result+i)=(int*)malloc(sizeof(int)*line);}if(NULL==*(result+i)){exit(0);}printf("请输入矩阵A:");/*输入矩阵数据(按二维数组存放)*/for(i=0;i<row1;i++){for(j=0;j<line1;j++)scanf("%d",&p[i][j]);}printf("\n原本的矩阵A是:\n");for(i=0;i<row1;i++){for(j=0,n=1;j<line1;j++,n++)/*当输入数据的个数是矩阵列数的整数倍时,换行显示(即显示成矩阵的形式)*/{if((n%line1==0)&&(j!=0))printf("%d\n",p[i][j]);elseprintf("%d\t",p[i][j]);}}printf("请输入矩阵B:");for(i=0;i<row2;i++){for(j=0;j<line2;j++)scanf("%d",&q[i][j]);}printf("\n原本的矩阵B是:\n");for(i=0;i<row2;i++){for(j=0,n=1;j<line2;j++,n++){if((n%line==0)&&(j!=0))printf("%d\n",q[i][j]);elseprintf("%d\t",q[i][j]);}}for(i=0;i<row;i++){for(j=0;j<line;j++)result[i][j]=0;}intk=0;for(i=0;i<row;i++)for(j=0;j<line;j++)for(k=0;k<line1;k++)result[i][j]+=p[i][k]*q[k][j];printf("\n两个矩阵相乘的结果是:\n");for(i=0;i<row;i++){for(j=0,n=1;j<line;j++,n++){if((n%line==0)&&(j!=0))printf("%d\n",result[i][j]);elseprintf("%d\t",result[i][j]);}}for(i=0;i<row1;i++)/*释放原本根据需要开辟的指针空间*/{free(*(p+i));p[i]=NULL;}free(p);p=NULL;for(i=0;i<row2;i++){free(*(q+i));q[i]=NULL;}free(q);q=NULL;for(i=0;i<row;i++){free(*(result+i));result[i]=NULL;}free(result);result=NULL;}}voidshucheng()/*定义实现矩阵数乘的函数*/{ inti=0,j=0,line=0,row=0,n=1,k; int**p=NULL; int**q=NULL; printf("请输入矩阵的行数:"); scanf("%d",&row); printf("请输入矩阵的列数:"); scanf("%d",&line); p=(int**)malloc(sizeof(int*)*row); if(NULL==p) exit(0); for(i=0;i<row;i++) {*(p+i)=(int*)malloc(sizeof(int)*line); if(NULL==*(p+i)) exit(0);} for(i=0;i<row;i++) {for(j=0;j<line;j++) scanf("%d",&p[i][j]);} printf("原本的矩阵是:\n"); for(i=0;i<row;i++) {for(j=0;j<line;j++,n++) {if((n%line==0)&&(j!=0)) printf("%d\n",p[i][j]); else printf("%d",p[i][j]);} } printf("\n"); q=(int**)malloc(sizeof(int*)*row); if(NULL==q) exit(0); for(i=0;i<row;i++) {*(q+i)=(int*)malloc(sizeof(int)*line); if(NULL==*(q+i)) exit(0);} printf("\n请输入需要数乘的数:"); scanf("%d",&k); for(i=0;i<row;i++) {for(j=0;j<line;j++) q[i][j]=k*(p[i][j]);}printf("\n数乘后的矩阵是:\n"); for(i=0;i<row;i++) {for(j=0,n=1;j<line;j++,n++) {if((n%line==0)&&(j!=0)) printf("%d\n",q[i][j]); else printf("%d",q[i][j]);} } for(i=0;i<row;i++) {free(*(p+i)); p[i]=NULL;} free(p); p=NULL; for(i=0;i<row;i++) {free(*(q+i)); q[i]=NULL;} free(q); q=NULL;}voidzhuanzhi()/*定义实现矩阵转置的函数*/{ inti=0,j=0,line=0,row=0,n=1; int**p=NULL; int**q=NULL; printf("请输入矩阵的行数:"); scanf("%d",&row); printf("请输入矩阵的列数:"); scanf("%d",&line); p=(int**)malloc(sizeof(int*)*row); if(NULL==p) exit(0); for(i=0;i<row;i++) {*(p+i)=(int*)malloc(sizeof(int)*line); if(NULL==*(p+i)) exit(0);} printf("请输入矩阵:\n"); for(i=0;i<row;i++) {for(j=0;j<line;j++) scanf("%d",&p[i][j]);} printf("原本的矩阵是:\n"); for(i=0;i<row;i++) {for(j=0;j<line;j++,n++) {if((n%line==0)&&(j!=0)) printf("%d\n",p[i][j]); else printf("%d",p[i][j]);} } printf("\n"); q=(int**)malloc(sizeof(int*)*line); if(NULL==q) exit(0); for(i=0;i<line;i++) {*(q+i)=(int*)malloc(sizeof(int)*row); if(NULL==*(q+i)) exit(0);} for(i=0;i<row;i++) {for(j=0;j<line;j++) q[j][i]=p[i][j];}/*原矩阵和转置后的矩阵行数和列数对调*/ printf("转置后的矩阵是:\n"); for(i=0;i<line;i++) {for(j=0,n=1;j<row;j++,n++) {if((n%row==0)&&(j!=0)) printf("%d\n",q[i][j]); else printf("%d",q[i][j]);} } printf("\n"); for(i=0;i<row;i++) {free(*(p+i)); p[i]=NULL;} free(p); p=NULL; for(i=0;i<line;i++) {free(*(q+i)); q[i]=NULL;} free(q); q=NULL;}voidjian()/*定义实现矩阵减法的函数*/{ inti=0,j=0,line1=0,row1=0,line2=0,row2=0,n=1; int**p=NULL; int**q=NULL; int**result=NULL; printf("请输入矩阵1的行数:"); scanf("%d",&row1); printf("请输入矩阵1的列数:"); scanf("%d",&line1); p=(int**)malloc(sizeof(int*)*row1); if(NULL==p) exit(0); for(i=0;i<row1;i++) {*(p+i)=(int*)malloc(sizeof(int)*line1); if(NULL==*(p+i)) exit(0);} printf("请输入矩阵1:"); for(i=0;i<row1;i++) {for(j=0;j<line1;j++) scanf("%d",&p[i][j]);} printf("原本的矩阵1是:\n"); for(i=0;i<row1;i++) {for(j=0;j<line1;j++,n++) {if((n%line1==0)&&(j!=0)) printf("%d\n",p[i][j]); else printf("%d\t",p[i][j]);} } printf("\n"); printf("请输入矩阵2的行数:"); scanf("%d",&row2); printf("请输入矩阵2的列数:"); scanf("%d",&line2); if((line1!=line2)||(row1!=row2))/*判断两个矩阵是否可以相减,如果两个矩阵的行数不等或者列数不等即不可相减,结束程序*/ {printf("\n无法相减!\n"); exit(0);} q=(int**)malloc(sizeof(int*)*row2); if(NULL==q) exit(0); for(i=0;i<row2;i++) {*(q+i)=(int*)malloc(sizeof(int)*line2); if(NULL==*(q+i)) exit(0);} printf("请输入矩阵2:"); for(i=0;i<row2;i++) {for(j=0;j<line2;j++) scanf("%d",&q[i][j]);} printf("原本的矩阵2是:\n"); for(i=0;i<row2;i++) {for(j=0,n=1;j<line2;j++,n++) {if((n%line2==0)&&(j!=0))/*若两个矩阵行数和列数都相等,执行运算*/ printf("%d\n",q[i][j]); else printf("%d\t",q[i][j]);} } introw,line; if((row1==row2)&&(line1==line2)) {row=row1; line=line1; result=(int**)malloc(sizeof(int*)*row); if(NULL==result) exit(0); for(i=0;i<row;i++) {*(result+i)=(int*)malloc(sizeof(int)*line); if(NULL==*(result+i)) exit(0);} } printf("\n"); for(i=0;i<row;i++) {for(j=0;j<line;j++) result[i][j]=p[i][j]-q[i][j];} printf("\n运算后的结果是:\n"); for(i=0;i<row;i++) {for(j=0,n=1;j<line;j++,n++) {if((n%line==0)&&(j!=0)) printf("%d\n",result[i][j]); else printf("%d\t",result[i][j]);}} for(i=0;i<row;i++) {free(*(p+i)); p[i]=NULL;} free(p); p=NULL; for(i=0;i<row;i++) {free(*(q+i)); q[i]=NULL;} free(q); q=NULL; for(i=0;i<row;i++) {free(*(result+i)); result[i]=NULL;} free(result); result=NULL;} voidadd()/*定义实现矩阵加法的函数*/{ inti=0,j=0,line1=0,row1=0,line2=0,row2=0,n=1; int**p=NULL; int**q=NULL; int**result=NULL; printf("请输入矩阵1的行数:"); scanf("%d",&row1); printf("请输入矩阵1的列数:"); scanf("%d",&line1); p=(int**)malloc(sizeof(int*)*row1); if(NULL==p) exit(0); for(i=0;i<row1;i++) {*(p+i)=(int*)malloc(sizeof(int)*line1); if(NULL==*(p+i)) exit(0);} printf("请输入矩阵1:"); for(i=0;i<row1;i++) {for(j=0;j<line1;j++) scanf("%d",&p[i][j]);} printf("原本的矩阵1是:\n"); for(i=0;i<row1;i++) {for(j=0;j<line1;j++,n++) {if((n%line1==0)&&(j!=0)) printf("%d\n",p[i][j]); else printf("%d\t",p[i][j]);} } printf("\n"); printf("请输入矩阵2的行数:"); scanf("%d",&row2); printf("请输入矩阵2的列数:"); scanf("%d",&line2); if((line1!=line2)||(row1!=row2)) {printf("\n无法相加!\n"); exit(0);} q=(int**)malloc(sizeof(int*)*row2); if(NULL==q) exit(0); for(i=0;i<row2;i++) {*(q+i)=(int*)malloc(sizeof(int)*line2); if(NULL==*(q+i)) exit(0);} printf("请输入矩阵2:"); for(i=0;i<row2;i++) {for(j=0;j<line2;j++) scanf("%d",&q[i][j]);} printf("原本的矩阵2是:\n"); for(i=0;i<row2;i++) {for(j=0,n=1;j<line2;j++,n++) {if((n%line2==0)&&(j!=0)) printf("%d\n",q[i][j]); else printf("%d\t",q[i][j]);} } introw,line; if((row1==row2)&&(line1==line2)) {row=row1; line=line1; result=(int**)malloc(sizeof(int*)*row); if(NULL==result) exit(0); for(i=0;i<row;i++) {*(result+i)=(int*)malloc(sizeof(int)*line); if(NULL==*(result+i)) exit(0);} } printf("\n"); for(i=0;i<row;i++) {for(j=0;j<line;j++) result[i][j]=p[i][j]+q[i][j];} printf("\n运算后的结果是:\n"); for(i=0;i<row;i++) {for(j=0,n=1;j<line;j++,n++) {if((n%line==0)&&(j!=0)) printf("%d\n",result[i][j]); else printf("%d\t",result[i][j]);}} for(i=0;i<row;i++) {free(*(p+i)); p[i]=NULL;} free(p); p=NULL; for(i=0;i<row;i++) {free(*(q+i)); q[i]=NULL;} free(q); q=NULL; for(i=0;i<row;i++) {free(*(result+i)); result[i]=NULL;} free(result); result=NULL;}4.调试分析:先把各个函数分开调试,运行无误后再把所有函数放入同一个文件中运行,这样有利于快速找出错误并改正。下图是主函数运行出现的首画面:以下先以乘法为例,展示不能计算时的运行结果:接下来从加法开始,展示运算的过程:(减法与加法类似,在此不进行赘述)若选择“1是”便会再次出现选择运算类型的选项如下图所示是乘法运行结果:以下是数乘:以下是转置:5.设计总结及心得体会:由于本人c语言水平有限,本程序虽然能够通过while循环来达到多次运算的目的,但是每次的运算都只能是两个矩阵进行计算,而后将计算结果赋值给第三方,不能做到一次性将多个矩阵相加(或相减、相乘等等)。这是本程序的一大缺点。不过本程序是动态开辟二维数组并且到函数结尾释放所占用的空间,运用到了与二维指针有关的c语言知识,巩固了过去所学。还多次运用到for语句,感到for语句的使用比while和do…while型简洁灵活一些,适用范围也更广泛。而且本函数需要特别注意循环的嵌套。在调试时不仅要关注程序是否能顺利进行,还要关注计算结果是否正确,要有一定的线性代数的知识。•参考文献:《c程序设计(第四版)》谭浩强著清华大学出版社《线性代数》陈建龙周建华韩瑞珠周后型编科学出版社6.答辩记录:____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________7.教师意见:______________________________________________________________________________________________________________________________________

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论