大学东南大学C语言课程设计报告.docx
《大学东南大学C语言课程设计报告.docx》由会员分享,可在线阅读,更多相关《大学东南大学C语言课程设计报告.docx(18页珍藏版)》请在冰点文库上搜索。
![大学东南大学C语言课程设计报告.docx](https://file1.bingdoc.com/fileroot1/2023-5/25/3b847f27-d7b9-419b-b9c5-f6f076d618d7/3b847f27-d7b9-419b-b9c5-f6f076d618d71.gif)
大学东南大学C语言课程设计报告
【关键字】大学
东南大学
C语言课程设计报告
课程名称:
计算机综合课程设计
学院:
土木工程学院
设计题目:
n阶方阵求逆矩阵
级别:
B
学生姓名:
汤佳敏
学号:
05111305
同组学生:
学号:
指导教师:
卢瑞华
月6日
一、题目与要求…………………………………2
二、项目分析……………………………………2
三、模块分析……………………………………4
四、程序分析……………………………………6
五、结果…………………………………………11
六、总结…………………………………………15
附:
参照文献
一、题目与要求
(1)题目:
n阶方阵求逆(B级)
功能要求:
a)输入一个n(n<256)阶方阵A,方程系数矩阵与向量均从文本文件读入;
b)输出A的逆矩阵至文本文件;
c)将得到的逆矩阵与矩阵A相乘,验证其结果是否为单位矩阵。
提示:
具体算法可参照相关文献。
(2)课程设计要求
Ø采用模块化程序设计;
Ø鼓励可视化编程;
Ø源程序中应有足够的注释;
Ø学生可自行增加新功能模块(视情况可另外加分);
Ø必须上机调试通过;
Ø注重算法运用,优化存储效率与运算效率;
Ø需提交源程序(含有注释)及相关文件(数据或数据库文件);
(cpp文件、txt或dat文件等)
Ø提交设计报告书,具体要求见以下说明。
二、项目分析
这是一道有关矩阵的问题,在我们设计程序之前,首先必须清楚了解方阵与方阵逆矩阵的定义,同时在此基础上掌握求解方阵逆矩阵及矩阵的乘法的问题。
我们都知道:
设A为n阶方阵,如果存在n阶方阵B,使得
AB=BA=E,
则称A是可逆的,并称B是A的逆矩阵。
否则,便说A是不可逆的。
在此基础上我们可以根据矩阵与逆矩阵的定义,即矩阵A与矩阵B相乘等于单位矩阵的思路,编辑程序。
但是,若用定义的方法求解,计算量大,当矩阵的阶数很大时很浪费时间。
为了节省时间,通过查阅各种资料和上网搜索,在数学问题中,求解方阵逆矩阵的方法有还有很多。
其中比较常见的一种方法就是用初等变换求方阵的逆矩阵,即高斯消元法求逆矩阵。
高斯消元法可以用来找出一个可逆矩阵的逆矩阵。
设A为一个N*N的矩阵,其逆矩阵可被两个分块矩阵表示出来。
将一个N*N单位矩阵放在A的右手边,形成一个N*2N的分块矩阵B=[A,I]。
经过高斯消元法的计算程序后,矩阵B的左手边会变成一个单位矩阵I,而逆矩阵A-1会出现在B的右手边。
我们不妨举个例子。
例1:
假如高斯消元法不能将A化为三角形的格式,那就代表A是一个不可逆的矩阵。
例2:
而对于矩阵的乘法,利用矩阵乘法定义即可实现,矩阵的乘法的定义是:
若A是一个m*n阶矩阵,B是一个n*p阶矩阵,则AB=C是一个m*p阶矩阵,而C中的每一个(i,j)元都等于A的第i行中的各元和B的第j列的各对应元之乘积的和。
只要按照该定义就可以求出两个矩阵的乘积。
最后必须解决的是文本文件数据的输入输出问题,这一点比较简单。
我们仅需掌握正确的输入输出格式即可。
综合考虑各种原因下面我们将用C语言实现高斯消元法求解方阵逆矩阵的问题。
三、模块分析
该程序主要分为七部分,分别为:
文件的读入部分、判断是否为逆矩阵部分、单位化矩阵部分、消元部分、打印步骤部分、检验乘积部分及输出部分。
其中单位化和消元部分是本程序设计的核心,即高斯消元法的主要步骤,具体程序如下:
for(j=n*2-1;j>=i;j--)
a[i][j]/=a[i][i];//单位化矩阵
for(j=0;jif((j!
=i)&&(abs(a[j][i])>err))
{
for(k=n*2-1;k>=i;k--)
a[j][k]-=a[i][k]*a[j][i]/a[i][i];//消元
}
这两部分均采用循环结构来操作,具体的运算一目了然,而for语句的使用增加了程序的可读性和简便性。
同时,判断矩阵是否可逆也是程序十分重要的一部分,在设计编写程序的前期,我遗漏掉了判断矩阵逆矩阵的功能模块,所以当在文本中输入一些矩阵后,程序无法正常的运行,进过思考和调试后我加上了如下的部分,通过布尔型变量的定义和使用,我们可以比较方便的判断矩阵是否可逆:
boolgot=false;//定义布尔型变量
for(j=i;jif(abs(a[j][i])>err)
{
got=true;
for(k=0;k{
l=a[j][k];
a[j][k]=a[i][k];
a[i][k]=l;
}
break;//找到第一个不为零的数则跳出列循环
}
if(!
got)
{
printf("singularmatrix.\n");
return0;
}//如果某一行全为零则无逆矩阵
还有便是矩阵相乘的部分,这一部分我们可以参考m*n阶矩阵与n*p阶矩阵相乘的程序,利用循环结构来实现:
printf("A*A^-1=\n");
for(i=0;i{
for(j=0;j{
l=0;
for(k=0;kl+=a[i][k+2*n]*a[k][j+n];
printf("%.2lf",l+err);//判断逆矩阵与原矩阵的乘积是否为单位矩阵
上图是设计的程序的算法流程图。
通过对程序的编写、调试与运行,最终验证了程序的准确性。
四、程序分析
如下是程序的源代码:
//采用高斯消元法
#include
#include
#definemaxn1000
#defineerr1e-8//宏定义保证计算中准确性
doublea[maxn][maxn*3];//maxn是代码最大元素的下标
doubleabs(doublea)//返回传递给它的参数的绝对值函数
{
if(a>0)returna;
elsereturn-a;
}//定义绝对值函数
intmain()
{
printf("Nowreadthematrixfromm.txt..\n");
intn,i,j,k;
doublel;
FILE*f1=fopen("m.txt","r");
fscanf(f1,"%d",&n);//从文本文件读入方程系数矩阵
memset(a,0,sizeof(a));//数组a初始化
for(i=0;ifor(j=0;j{
fscanf(f1,"%lf",&a[i][j]);//从文本读入矩阵
a[i][j+2*n]=a[i][j];//在n*2n阶矩阵后再加上原矩阵形成n*3n阶矩阵
}
fclose(f1);
printf("Donereading.\n");
for(i=0;ia[i][i+n]=1;//建立单位矩阵,即将单位矩阵变成伴随矩阵
for(i=0;i{
boolgot=false;//定义布尔型变量
for(j=i;jif(abs(a[j][i])>err)
{
got=true;
for(k=0;k{
l=a[j][k];
a[j][k]=a[i][k];
a[i][k]=l;
}
break;//找到第一个不为零的数则跳出列循环
}
if(!
got)
{
printf("singularmatrix.\n");
return0;
}//如果某一行全为零则无逆矩阵
for(j=n*2-1;j>=i;j--)
a[i][j]/=a[i][i];//单位化矩阵
for(j=0;jif((j!
=i)&&(abs(a[j][i])>err))
{
for(k=n*2-1;k>=i;k--)
a[j][k]-=a[i][k]*a[j][i]/a[i][i];//消元
}
//打印每步化简及计算过程
printf("Step%i:
\n",i);
for(j=0;j{
for(k=0;kprintf("%.2lf",a[j][k]);
printf("\n");
}
printf("\n\n");
}
printf("Donenijvzhengwei:
\n\n");
for(i=0;i{
for(j=0;jprintf("%.2lf",a[i][j+n]);
printf("\n");//在程序中输出逆矩阵
}
printf("\n");
printf("nijvzhengyijinshuruzhiwenbenwenjian“ans.txt”.\n\n");//逆矩阵已经输入至文本文件"ans.txt"
f1=fopen("ans.txt","w");
fprintf(f1,"%i\n",n);
for(i=0;i{
for(j=0;jfprintf(f1,"%.2lf",a[i][j+n]);
fprintf(f1,"\n");
}
fclose(f1);//输出逆矩阵
printf("A*A^-1=\n");
for(i=0;i{
for(j=0;j{
l=0;
for(k=0;kl+=a[i][k+2*n]*a[k][j+n];
printf("%.2lf",l+err);//判断逆矩阵与原矩阵的乘积是否为单位矩阵
}
printf("\n");
}
printf("\n");
return0;
此程序整体是采用数组和循环来完成的,在了解了高斯消元法的具体算法后,我们可以很快的编出上述程序。
在运算的过程中,我们要判断一些数据是否为零,这时候我们采用宏定义#defineerr1e-8方式,通过将零与e-8进行比较,可以保证我们计算的准确性。
考虑到我们更加直观的看到单位化和消元的过程,我通过打印每步的步骤来使程序明了,当然这样输出界面也就不太简洁了。
此程序中判断矩阵是否可逆是很重要的一部分,这决定了后续步骤逆矩阵与原矩阵是否需要被运行。
当然该程序仍存在一些不足之处,希望老师能够提出一些改进的建议。
五、结果
在程序的调试过程中,出现了许多问题,一是一些语法的错误和人为的失误。
如在编写程序的过程中丢失了一些分号,双引号等等。
还有就是起初,我只会进行文本文件不按格式的读入。
文本文件中的数据读入后,无论其格式如何只显示在运行时只显示一行数字。
翻阅了一些资料后,我将读取文本数据的模块部分调整为如下:
FILE*f1=fopen("m.txt","r");
fscanf(f1,"%d",&n);//从文本文件读入方程系数矩阵
memset(a,0,sizeof(a));//数组a初始化
for(i=0;ifor(j=0;j{
fscanf(f1,"%lf",&a[i][j]);//从文本读入矩阵
即是对方程的系数和矩阵按格式分别进行读入。
下面是此程序所存在的几种可能情形的截图:
1不存在逆矩阵:
不存在逆矩阵的情形有很多种,可能是初始矩阵的某行全为零,也有可能是初始矩阵经过变化之后其某行全部变为零。
此时,无答案输出至文本文件。
2存在逆矩阵的情形,这里选取了一6阶方阵,
如图所示为一6阶方阵,在VC中运行运行后,我们可以得到如下的结果
如图所示我们可以清楚的看到,程序在将从文本输入的矩阵变成增广矩阵之后,分别对每一行元素进行单位化和消元,得出最后的结果后,将所得矩阵输入至文本文件“ans.txt”,最终将所得的逆矩阵与原矩阵相乘检验其是否为逆矩阵。
同样的对于更高阶的方阵此程序仍旧适用。
六、总结
从上学期接触C语言来,在学习这门课程上我便一直存在很大问题,在学习上总是感觉力不从心。
曾经一度想到过放弃,但是仍旧坚持了下来。
这个短学期的课程设计可以说让我再次认识了C语言。
这是我第一次有机会用C语言来解决实际的数学问题,这一改C语言在我脑海里枯燥和乏味的形象,原来C语言的魅力竟可以如此之大!
由于在工程建设中经常遇到一些矩阵的计算问题,所以在选题时我便选取了求方阵逆矩阵这一问题。
当我开始着手做这道题目时,我愕然了,完全不知道从何处下手。
对于模拟题,从前并未接触很多,何况是和矩阵有关的题目。
所以在找到正确的解题方法前,内心一直感到惴惴不安。
幸运的是,在上机的时候老师给予了我帮助和指导,才让我弄清楚了题目的要求,于是我开始着手查找各种资料,翻阅和线性代数求解逆矩阵有关的书籍,在综合考虑到各种算法的简便性问题后,最终开始了程序的设计和调试之旅。
这次课程设计让我收获颇多,一是在程序设计和调试的能力上。
通过这次程序设计,我复习和巩固了c语言的基础知识、加深对c语言编程的理解;同时在编程的过程中,我程序的开发、调试、测试能力也得到了提高,对C语言也建立起了比较浓厚的兴趣。
当然在程序编写的过程中,我也遇到了不少问题。
首先是最简算法的寻找问题。
我们都知道,求方阵逆矩阵的方法有很多,如用初等行变换(初等列变换)或者利用伴随矩阵除以矩阵的行列式求得。
而如何选取最简方法并将其改成计算机语言是一件十分繁琐的事。
考虑到求解n阶方阵的行列式和n阶方阵的伴随矩阵的计算量比较大,所以如果采用这种方法求解方阵逆矩阵,系统的运算效率会大大减弱。
所以综合考虑程序的简便性以及可实施性,我最选择利用初等行变换即高斯消元法求方阵的逆矩阵。
其次是关于文件的输入输出问题,刚开始,我一直对文件的输入输出很迷惑。
起初试了几个格式,都只能够从文本中无格式的读入数据,于是我在图书馆翻阅了一些C程序集,经过几次调试终于得出了结果。
俗话说:
“有志者,事竟成,破釜沉舟,百万秦关终属楚。
苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
”终于在我的不懈努力下,终于能够按格式输入数据。
总结下来这次课程设计的感悟可以概括为以下几点:
一是在我们设计程序时,我们首先要自己弄清楚如何在现实中解决这个问题,即成为电脑的大脑,思考解决问题的方法。
掌握解决问题的工具,我们方能高效的解决问题。
二是程序的具体语言并不是十分重要,一个程序的核心是算法与清晰的思路,在解题的过程中我们可以借助流程图来帮助我们对题目进行整体的理解和掌握。
同时我们要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方。
三是程序设计不是一件一蹴而就的事,往往我们要进过反复运行和调试才能得出最后的结果。
学习如钻探石油,钻得愈深,愈能找到知识的精髓。
先学爬,然后学走,我们做事要循序渐进,学会凡事不放弃。
总的来说,这次C程序课程设计对我来说是一次挑战。
也感谢老师在我编程中对我给予的帮助与支持。
今后我一定会利用一切资源好好学习C语言,不断的探索其无穷的奥妙。
附:
参考文献
【1】线性代数科学出版社陈建龙周建华韩瑞珠周后型编
【2】C程序设计(第四版)清华大学出版社
此文档是由网络收集并进行重新排版整理.word可编辑版本!