1、 沈 阳 航 空 工 业 学 院 课程设计 班 级 :6402104班 学 号 :200604021139 姓 名 :郑松 指导教师 :刘成 07年9 月14日 课程设计任务书 院系:电子 专业:电子信息工程 班级:6402104 学号:200604021139 题目:用高斯列主元消元法解线性方程组 一、课程设计时间 2007年9月10日至2007年9月14日,共计1周,20学时。 二、课程设计内容 用C语言编写软件完成以下任务: 请用高斯列主元消元法解下列线性方程组:
2、 三、课程设计要求 1. 程序质量: ² 贯彻结构化的程序设计思想。 ² 用户界面友好,功能明确,操作方便。 ² 用户界面中的菜单至少应包括“输入数据”、“开始计算”、 “退出”3项。 ² 代码应适当缩进,并给出必要的注释,以增强程序的可读性。 2. 课程设计说明书: 课程结束后,上交课程设计说明书和源程序。课程设计说明书的格式和内容参见提供的模板。 四、指导教师和学生签字 指导教师:________ 学生签名:________ 五、成绩: 六、教师评语: 目 录 一、程序设计题目 1 二、需求分析(高斯列主元消元法) 1 三、程
3、序流程图 3 四、核心技术的实现方法及程序段 6 五、个人总结 8 六、参考文献 9 七、源程序 9 沈 阳 航 院 设 计 用 纸 一、程序设计题目 用C语言编写软件完成以下任务: 请用高斯列主元消元法解下列线性方程组: 二、需求分析(高斯列主元消元法) 方法说明(以4阶为例): 第1步消元——在增广矩阵(A,b)第一列中找到绝对值最大的元素,将其所在行与第一行交换,再对(A,b)做初等行变换使原方程组转化为如下形式: 第2步消元——在增广矩阵(A,b)中的第二列中(从第二行开始)找到绝对值最大的元素,将其所在行与第二行交换,再对
4、A,b)做初等行变换使原方程组转化为: 第3步消元——在增广矩阵(A,b)中的第三列中(从第三行开始)找到绝对值最大的元素,将其所在行与第二行交换,再对(A,b)做初等行变换使原方程组转化为: 按x4 à x3à x2à x1 的顺序回代求解出方程组的解 附:下面三种变换称为初等行变换: ① 对调两行; ② 以数k≠0乘某一行中的所有元素; ③ 把某一行所有元素的k倍加到另一行对应的元素上去。 按照解题的思路,整个程序大概由以下几个部分组成:输入方程组;判断线性方程组是否合法;交换行的矩函数(change);比较系数大
5、小的函数(mymax);菜单的选择(message);开始计算;退出程序等。除了以上主要部分外,程序还用到了if.和switch选择语句,对程序的进一步简化起到重要作用,使源程序显的更加简洁明了。 三、程序流程图 总体流程图(一) 定义数组x[NUMBER],变量r,k,i,j,celect 判断celect是否等于esc 是 否 i = 1 i <=
6、n 输入系数和向量 j = 1 j <= n+1 将输入的数据存入A[i][j]中 退 j ++ i ++ k = 1 k <= n-1 出 调用mymax函数比较系数大小 判断ark是否等于零
7、 是 否 判断f是否不等于k 是 否 此方程组不合法 调用change 不执行 函数 i = k+1 i <= n j = k+1 j <= n+1
8、 j ++ k ++ x[n]=A[n][n+1]/A[n][n] k = n-1 k >=1 j = k+1 j <= n me = me + A[k][j] * x[j] j ++
9、 k -- 输出结果 调用message函数 A[i][j] = A[i][j] – A[k][j] * A[i][k] / A[k][k] 出 j ++ k ++ x[u] = A[n][n+1] / A[n][n]
10、求解最后一个方程组的解 k = n - 1 k >= 1 j = k + 1 j <= n p1= p1 + A[k][j] * x[j] j ++ k -- 输出线性方程组的结果 调用message函数 变换行的函数流程图(二) 定义变量 i=1 i<=n+1 i++ A[0][i]=A[r][i] A[r][i]=A[k][i] A[k][i]=A[0][i]
11、 判断系数大小的流程图(三) 定义变量k,I,p2 判断fabs(A[i][k])是否大于p2 是 否 i=k i<=n i++ 不 p2=fabs(A[i][k]) 执 f=i 返回p2的值 行
12、 实现菜单选择的流程图(四) 开始 输出提示信息 输入变量值值值值量 入变量值 退出 返回主函数 输出信息 结束 程序运行结果如图: (图一) (图二) 若线性方程组为四维方程时:
13、 (图三) 四、核心技术的实现方法及程序段 源程序主要由三个自定义函数和一个主函数组成,其中主函 数以菜单的形式调用其他函数来实现要求的所有功能。在这些函数中交换行的距函数、比较系数大小的函数和实现菜单选择的函数是程序中较为核心的部分,下面分别进行说明: 1、 此模块通过change()函数改变矩阵行的顺序 ,具体程序段如下: change(int r,int k) /*交换行的矩函数*/ { int i; for(i=1;i<=n+1;i++) A[0][i]=A[r]
14、[i]; for(i=1;i<=n+1;i++) A[r][i]=A[k][i]; for(i=1;i<=n+1;i++) A[k][i]=A[0][i]; } 2、 此模块通过mymax()函数实现矩阵行的升序排列,具体程序段如下: float mymax(int m) /*比校系数大小的函数*/ { int i; float p2=0; for(i=m;i<=n;i++) if(fabs(A[i][m])>p2) { P2=fabs(A[i][m]); f=i
15、 } return p2; } 3、 模块通过message函数实现程序的重新运算,否则退出,错误则不执行,至此程序完毕,具体程序段如下: message() /*实现菜单选择的函数*/ { printf("\n\n 继续运算按 Enter ,退出程式按 Esc!"); switch(getch()) { case Enter: main(); case Esc: exit(0); default: { printf("\
16、n\n不合法的输入!"); message(); } } 五、个人总结 一整周的课程设计艰难奋斗的同时让我学会了很多C语言的知识,使我对C语言更充分的认识了它的实用性,自己基本掌握了有关函数与循环语句的用法及规则。该程序完成不是一帆风顺的,在编写过程中遇到了许多的疑难问题有幸得到了同学与老师的帮助,同时自己也翻阅了相关书籍,努力编好与完善。刚开始对自己解线性方程组的课题无从下手,对用“高斯列主消元法”更是莫名其妙。虽然源程序不是非常完美,不过在自己的不屑努力下还是完成了课题。这次课设在一定程度上给自己的创新充分到发挥,希望以后能有更多的机会参加课程设计。
17、
六、参考文献
1 谭浩强.C程序设计.北京:清华大学出版社,2005
2 刘成等.C语言程序设计实验指导与习题集.北京:中国铁道出版社,2006
七、源程序
#include
18、] ,ark; int f,n; change(int r,int k); float mymax(int m); message(); main() { float x[number]; /*定义数组X[]用于储存方程组的解*/ int r,k,i,j; char celect; printf("\n\n用Gauss列主元消元法解线性方程组"); printf("\n\n1.开始解方程组请按Enter."); printf("\n\n2.退出程式请按Esc."); celect=getch();
19、if(celect==Esc) exit(0); printf("\n\n 请输入方程组的维数:n="); scanf("%d",&n); printf(" \n\n现在输入方程组系数矩阵A和向量b:"); for(i=1;i<=n;i++) { printf("\n\n请输入a%d1--a%d%d系数和向量b%d:",i,i,n,i); /*把线性方程的系数复于数组中*/ for(j=1;j<=n+1;j++) scanf("%f",&A[i][j]); }
20、for(k=1;k<=n-1;k++) { ark=mymax(k); if(ark==0) /*判断线性方程组是否合法*/ { printf("\n\n此方程组无解!");message(); } else if(f!=k) change(f,k); for(i=k+1;i<=n;i++) for(j=k+1;j<=n+1;j++) A[i][j]=A[i][j]-A[k][j]*A[
21、i][k]/A[k][k]; /*此过程是对数组进行初等行变换*/ } x[n]=A[n][n+1]/A[n][n]; /*先求出最后一个未知数的解*/ for( k=n-1;k>=1;k--) { float p1=0; for(j=k+1;j<=n;j++) { p1=p1+A[k][j]*x[j]; } x[k]=(A[k][n+1]-p1)/A[k][k]; /*对线性方程组求解的运算(依次求的前面的、未知树的解)*/
22、 } for(i=1;i<=n;i++) { printf(" \n\nx%d=%f",i,x[i]); } message(); } change(int r,int k) /*交换行的函数 */ { int i; for(i=1;i<=n+1;i++) A[0][i]=A[r][i]; for(i=1;i<=n+1;i++) A[r][i]=A[k][i]; for(i=1;i<=n+1;i++) A[k][i]=A[0][i];
23、} float mymax(int m) /*比较系数大小的函数*/ { int i; float p2=0; for(i=m;i<=n;i++) if(fabs(A[i][m])>p2) /*对数组中的元素进行取绝对值比较大小的运算*/ { p2=fabs(A[i][m]); f=i; } return p2; } message() /*菜单选择的函数*/ { printf("\n\n 继续运算按 Enter ,退出程式按 Esc!"); switch(getch()) { case Enter: main(); case Esc: exit(0); default:{printf("\n\n不合法的输入!");message();} } } 13






