资源描述
攀枝花学院课程设计
题 目: 计算器
院 (系): 数学与计算机学院
年级专业: 软件工程1班
姓 名: 刁刚健
学 号: 201510602008
指导教师:
二〇一六年七月五日
攀枝花学院教务处制
攀枝花学院本科学生课程设计任务书
题 目
计算器
1、课程设计的目的
通过完成一个完整项目,经历策划、设计、开发、测试、验收各阶段,达到:
(1)巩固和实践计算机图形学课程中的理论和算法;
(2)培养项目策划、架构设计、软件开发和科研设计的能力;
(3)培养认真学习、积极探索的工作态度和良好的团队合作精神。
2、课程设计的内容和要求(包括原始数据、技术要求、工作要求等)
开发工具:TC或Visual C++
开发人数:1人
实现内容:
设计开发一个计算器演示程序
功能要求:
(1)根据需求设计出图形显示界面
(2)根据计算器原理实现大小不同的盘子移动的全过程演示。
3、主要参考文献
[1] 潭浩强,《C++程序设计》,清华大学出版社
[2] 周霭如,《C++程序设计基础》,电子工业出版社
[3] 潭浩强,《C++程序设计题解与上机指导》,清华大学出版社
[4] 刘玲等,《C语言程序设计应用教程》,西南师范大学出版社
4、课程设计工作进度计划
序号
时间(天)
内容安排
备注
1
1
分析设计准备
周一
2
2
编程调试阶段
周二至周三
3
1
编写课程设计报告
周四
4
1
考核
周五
总计
5(天)
指导教师(签字)
日期
年 月 日
教研室意见:
年 月 日
学生(签字):
接受任务时间: 年 月 日
注:任务书由指导教师填写。
课程设计(论文)指导教师成绩评定表
题目名称
评分项目
分值
得分
评价内涵
工作
表现
20%
01
学习态度
6
遵守各项纪律,工作刻苦努力,具有良好的科学工作态度。
02
科学实践、调研
7
通过实验、试验、查阅文献、深入生产实践等渠道获取与课程设计有关的材料。
03
课题工作量
7
按期圆满完成规定的任务,工作量饱满。
能力
水平
35%
04
综合运用知识的能力
10
能运用所学知识和技能去发现与解决实际问题,能正确处理实验数据,能对课题进行理论分析,得出有价值的结论。
05
应用文献的能力
5
能独立查阅相关文献和从事其他调研;能提出并较好地论述课题的实施方案;有收集、加工各种信息及获取新知识的能力。
06
设计(实验)能力,方案的设计能力
5
能正确设计实验方案,独立进行装置安装、调试、操作等实验工作,数据正确、可靠;研究思路清晰、完整。
07
计算及计算机应用能力
5
具有较强的数据运算与处理能力;能运用计算机进行资料搜集、加工、处理和辅助设计等。
08
对计算或实验结果的分析能力(综合分析能力、技术经济分析能力)
10
具有较强的数据收集、分析、处理、综合的能力。
成果
质量
45%
09
插图(或图纸)质量、篇幅、设计(论文)规范化程度
5
符合本专业相关规范或规定要求;规范化符合本文件第五条要求。
10
设计说明书(论文)质量
30
综述简练完整,有见解;立论正确,论述充分,结论严谨合理;实验正确,分析处理科学。
11
创新
10
对前人工作有改进或突破,或有独特见解。
成绩
指导教师评语
指导教师签名: 年 月 日
攀枝花学院学生课程设计论文 摘要
摘 要
I
攀枝花学院学生课程设计论文 目录
目 录
摘 要 I
1 需求分析 1
1.1 需求概述 1
1.2 需求环境 1
1.3 功能描述 2
2 概要设计 3
2.1 程序功能模块 3
2.2 程序流程图 3
2.3 数据结构的设计 4
3 详细设计 5
3.1 程序初始化 5
3.1.1 代码功能 5
3.1.2 功能实现代码 5
3.2 盘块的移动过程 5
3.2.1代码功能 5
3.2.2 功能实现代码 5
3.3 递归函数 6
3.3.1 流程图 6
3.3.2 功能实现代码 7
4 测试与运行 8
结束语 9
参考文献 10
II
攀枝花学院学生课程设计论文 需求分析
1 需求分析
1.1 需求概述
汉诺塔演示程序设计是计算机图形学中图形变换的内容之一。而图形学中的图形变换的概念是由简单图形生成复杂图形,可用二维图形表示三维形体,甚至可以对静态图形经过快速变换而获得图形的动态显示效果。其任务是研究各点坐标之间的变化规律。而本次课程设计就是利用C语言以及图形函数实现汉诺塔的递归算法来进行其盘块移动的全过程显示。在TC环境中要实现这样的功能,就要牵涉到图形设备接口的知识。Windows图形设备接口是为与设备无关的图形设计的,是Windows系统的重要组成部分,负责系统与用户或绘图程序之间的信息交换,并控制在输出设备上显示图形或文字。应用程序必须通知图形设备接口来加载特定的设备驱动,一旦驱动得以加载,就可以准备应用设备进行相关的操作这些任务都要通过创建和维护设备描述表来完成。在实现汉诺塔演示程序设计时,是利用坐标系统而得到的,而在Windows应用程序中有两种坐标系统:设备坐标系统和逻辑坐标系统。其中设备坐标系统中又有三种相互独立的坐标系统:屏幕坐标系统、窗口坐标系统和用户区坐标系统。这些坐标系统均以像素点来表示度量的单位。屏幕坐标系统使用整个屏幕作为坐标区域,原点为屏幕原点。窗口坐标系统使用了边界在内的应用程序的窗口作为坐标区域。窗口边界的左上角是坐标系统的原点。用户坐标系统是最经常使用的坐标系统。用户区是窗口工作区,不包括窗口边界、菜单条及滚动条等。用户一般只需操作应用程序的用户区,因此用户区坐标系统对大多数应用程序都是适用的。
在计算机机图形学中窗口的定义是指在用户坐标系中定义的确定显示内容的一个矩形区域,只有在这个区域内的图形才能在设备坐标系下输出,而窗口外的部分则被截掉。视区是在设备坐标中定义的一个区域,用于输出窗口中的图形。视区决定了窗口中的图形要显示于屏幕上的位置的大小。
1.2 需求环境
本课程设计需要的设备为硬件要求和软件配置要求具体要求如下:
①硬件要求:一台计算机。
②软件配置:WINDOWS、C/VC++6.0。
1.3 功能描述
简单计算器包括双目运算和单目运算功能。双目运算符包含基本的四则运算及乘幂功能,单目运算符包含正余弦,阶乘,对数,开方,倒数等运算。可对输入任意操作数,包括小数和整数及正数和负数进行以上的所有运算并能连续运算。出现错误会给出相应提示,同时包含清除,退格,退出功能以及有与所有按钮相对应的菜单项。
16
攀枝花学院学生课程设计论文 概要设计
2 概要设计
2.1 程序功能模块
如图是整个计算器的流程图,打开计算器程序,输入数据,调用输入数据子程序。子程序开始时m_num为零。按下数字按钮后,判断m_num的正负号,对其进行相关处理,然后在判断是否有小数点,处理后输出结果。
回到总流程图中,输完第一个操作数后,若按下双目运算符,则把m_num存入num2,按下输入第二个操作数并算出结果。若按下的是单目运算符,则直接对其处理得出结果。若按下清零,则m_num等于0.在运算中还要判断运算是否合法,以及结果是否超出显示范围,以做出相关提示,按下清零。算出后把结果保存至num2。若需用算出的结果继续运算则回到输入完第一个操作数后,若不需要则判断试否需要开始新一轮的运算,不需要则结束。
2.2 程序流程图
N
N
Y
键入一个数
是否为正数?
m_num =10*m_num+i
m_num =10*m_num-i
是否为小数?
用UpdateData(FALSE)刷新显示
还原m_num
根据小数点后位数将键入的数除以n次10累加到m_num
Y
继续键入数字?
Y
输入数据子函数
编辑框关联变量m_num=0
Y
开始
输入数据子函数
编辑框关联的变量保存至num2
输入数据子函数
进行运算
运算是否合法
把结果保存到num2
m_num清零
弹出对话框显示ERROR
N
Y
是否用保存的结果继续进行运算
N
结束
jie
双目运算符
单目运算符
是否开始新一轮的计算
Y
N
2.3 数据结构的设计
根据需求分析将用递归算法实现计算器0演示过程的数据结构的设计如下:
① 用一个结构体数组struct M { int data[15]; int top; }num[3];来定义三个塔座的高度,以及每个塔座存放每个盘块的代号。
② 定义两个变量cx,cy来分别表示程序演示步骤的横坐标和纵坐标的变化。
③ 用函数void move(char x,char y,struct M num[3]);来表示盘块移动的具体过程;并在move函数中调用函数void hanoi(char x,char y,char z,int n,struct M num[3]);来表示递归调用的过程;最后用一个初始化函数void Init(void)来对整个程序进行初始化,并调用move函数。
攀枝花学院学生课程设计论文 详细设计
3 详细设计
3.1 程序初始化
3.1.1代码功能
在初始化程序中,主要实现的是画出结构框图和对计算器的各个按键的功能设置。
3.1.2 功能实现代码
1、09107xuzhujieDlg.h里变量的定义:
BOOL ele2; // ele定义为布尔值,判断当前值是否是正数还是负数
int addt;
int i;
int dint;//dent判断小数后的位数
BOOL ele; //ele2定义为布尔值,判断是否有小数点
double num2;
double num1;
2、程序运行时初始化和头文件:
m_num=0; //输出框清0
num1=0; //变量1为0
num2=0; //变量2为0
dint=0; //小数点位数
addt=0; //整数位数无
ele=FALSE; //当前无小数
ele2=TRUE;
09107xuzhujieDlg.cpp里加上头文件#include "math.h"
3、 数字键1的程序:(数字键2到9类似)
if(addt==0)num2=0;
if(ele2==TRUE)
m_num=m_num*10+1; //单击数字键1后把数据传送到输出框中
else m_num=m_num*10-1;
if (ele==TRUE) //当前是否有小数点,如果有
{
num1=1;
dint=dint++;
for (i=0;i<dint;i++)
{
num1=num1/10; //1/10,得到的小数放入输出框中
}
if (ele2==TRUE) //当前值是否是正数还是负数,如果是正数
m_num=(m_num-1)/10+num1; //前面不加负号
else
m_num=(m_num+1)/10-num1; //否则前面加负号
}
UpdateData(FALSE); //数据刷新
5、 加法键+的程序:(-,*,/,x,x^y的代码类似)
if(num2==0)
{num2=m_num; //把第二个值赋于输出框的成员变量
m_num=0; //输出框的成员变量清0
ele=FALSE; //当前小数无
ele2=TRUE; //当前符号为正
dint=0; //小数位数无
addt=1;
}
6、 Sqrt键的程序:
if(m_num!=0)num2=m_num;
if(m_num>=0)
{m_num=sqrt(num2); //对数进行开根号
UpdateData(FALSE); //数据刷新
num2=m_num;
}
else GetDlgItem(IDC_xianshi)->SetWindowText("错误,负数不能开根号");
m_num=0;
num1=0;
dint=0;
ele=FALSE;
ele2=TRUE;
7、n!键的程序:
if(m_num!=0)num2=m_num;
if(fmod(num2,1)==0)
{m_num=1;
for(i=1;i<=num2;i++)m_num*=i; //对数进行求阶乘
UpdateData(FALSE); //数据刷新
num2=m_num;
if(m_num>=1.7E308||m_num<-1.7E308)
GetDlgItem(IDC_xianshi)->SetWindowText("结果过大,无法显示");
}
else GetDlgItem(IDC_xianshi)->SetWindowText("不是整数无法进行阶乘运算");
m_num=0;
num1=0;
dint=0;
ele=FALSE;
ele2=TRUE;
8、1/x键的程序:
if(m_num!=0)num2=m_num;
if(num2!=0)
{
m_num=1.0/num2; //对数进行求倒数
UpdateData(FALSE);//数据刷新
num2=m_num;
if(m_num>=1.7E308||m_num<-1.7E308)
GetDlgItem(IDC_xianshi)->SetWindowText("结果过大,无法显示");
}
else GetDlgItem(IDC_xianshi)->SetWindowText("错误,0不能求倒数");
m_num=0;
num1=0;
dint=0;
ele=FALSE;
ele2=TRUE;
9、sin键的程序:(cos的代码类似)
if(m_num!=0)num2=m_num;
m_num=sin(num2*3.1415926/180); //对数进行正弦
UpdateData(FALSE); //数据刷新
num2=m_num;
m_num=0;
num1=0;
dint=0;
ele=FALSE;
ele2=TRUE;
10、ln键的程序:
if(m_num!=0)num2=m_num;
if(m_num>0)
{
m_num=log(num2); //对数进行求ln
UpdateData(FALSE); //数据刷新
num2=m_num;
}
else GetDlgItem(IDC_xianshi)->SetWindowText("错误,操作数需大于0");
m_num=0;
num1=0;
dint=0;
ele=FALSE;
ele2=TRUE;
11、=键的程序:
switch (addt) //数据判断
{
case 0: //为实现连续按下两次等号后能清零
UpdateData(FALSE); //数据刷新
break;
case 1:
m_num=num2+m_num; //两数相加
UpdateData(FALSE); //数据刷新
break;
case 2:
m_num=num2-m_num; //两数相减
UpdateData(FALSE); //数据刷新
break;
case 3:
m_num=num2*m_num; //两数相乘
UpdateData(FALSE); //数据刷新
break;
case 4:
if (m_num==0) //在除法中,判断除数是否为0
GetDlgItem(IDC_xianshi)->SetWindowText("错误,0不能作除数");
else {m_num=num2/m_num;UpdateData(FALSE);}
break;
case 5:
m_num=pow(num2,m_num); //取模
UpdateData(FALSE); //数据刷新
break;
}
if(m_num>=1.7E308||m_num<-1.7E308)
GetDlgItem(IDC_xianshi)->SetWindowText("结果过大,无法显示");
num2=m_num;
m_num=0;
num1=0;
dint=0;
ele=FALSE;
addt=0;
ele2=TRUE;
12、清除键Clear的程序:
m_num=0; //输出框清0
num1=0; //变量1为0
num2=0; //变量2为0
dint=0; //小数无位数
addt=0; //整数位数无
ele=FALSE; //当前无小数
ele2=TRUE;
UpdateData(FALSE); //数据刷新
13、退格键Backspace的程序:
if (ele==FALSE ) //判断当前是否有小数点,如果没有
m_num=m_num/10-fmod(m_num/10,1); //去掉小数位
else
{
if (ele==TRUE && dint>0) //如果是小数
{
for (i=0;i<dint-1;i++) //移动小数点
{
m_num=m_num*10; //移动至只有一个小数位
}
m_num=m_num-fmod(m_num,1); //去掉小数位
for (i=0;i<dint-1;i++) //小数点移至原来位置
{
m_num=m_num/10;
}
}
dint=dint--;
}
if (dint==0)ele=FALSE;
if(m_num==0)ele2=TRUE;
UpdateData(FALSE); //数据刷新
14、退出键Exit的程序:
OnOK() ;
15、关联关于对话框代码:
CAboutDlg dlgAbout;
dlgAbout.DoModal();
3.2 盘块的移动过程
3.2.1代码功能
盘块的移动实际上是一个出栈和入栈的过程,盘块出栈后便将原来的地方涂黑,本块代码主要是实现显示汉诺塔的具体移动的演示过程及移动步骤。
3.2.2 功能实现代码
void move(char x,char y,struct M num[3])/*移动的具体过程*/
{
int i;
char num1[3],num2[3];
sprintf(num1,"%c",x-32);/*将小写变成大写,并转换成字符串输出*/
sprintf(num2,"%c",y-32);
setfillstyle(SOLID_FILL,BLACK);/*把原来的地方移去涂黑*/
setcolor(YELLOW);
outtextxy(20+cx,30+cy,num1);/*输出移动过程,每次移动后纵坐标加30*/
outtextxy(62+cx,30+cy,"-->");
outtextxy(130+cx,30+cy,num2);
cy+=30;
if(cy>210) /*横坐标换行后另起一列*/
{ cx+=145;
cy=0;/*纵坐标重新回到顶部开始显示下一列的演示步骤 */
}
settextstyle(0,0,2);
setfillstyle(SOLID_FILL,BLACK);/*把原来的地方移去涂黑*/
bar(100+150*(x-97)-(33-3*num[x-97].data[num[x-97].top]),400-20*num
[x-97].top-8,100+150*(x-97)+(33-3*
num[x-97].data[num[x-97].top]),400-20*num[x-97].top+8);num[y-97].top++;/*入栈,目标点的top加1*/
num[y-97].data[num[y-97].top]=num[x-97].data[num[x-97].top];/*在目标点盘子的代号与源点盘子的代号相同*/
num[x-97].top--;/*出栈,原来地方的top减1*/
setfillstyle(SOLID_FILL,num[y-97].data[num[y-97].top]+1);/*盘子颜色代码是栈顶盘子代号加1*/
bar(100+150*(y-97)-(33-3*num[y-97].data[num[y-97].top]),400-20*
num[y-97].top-8,100+150*(y-97)+(33-3*num[y-97].data[num[y-97].top]),
400-20*num[y-97].top+8);
getch( );/*自己按键盘来进行手动控制*/
3.3 递归函数
3.3.1 流程图
根据概要设计中的实现递归函数过程的流程图设计如图3.3所示:
开 始
n= =1?
将盘块从A座移到C座
将前n-1个盘块从A座移到B座
再将A座的第n个盘块移到C座
最后将B座上的n-1个盘块移到C座
结 束
图3.1 递归函数
3.3.2 功能实现代码
汉诺塔演示程序设计主要是利用递归调用函数实现。函数调用hanoi( one,two,three,n,num)表示将n个盘块从A座移到C座的过程,函数调用move(one,three,num)是将1个盘块从A座移到C座的过程。其具体代码实现如下:
if(n==1)
move(one,three,num);/*如果盘子为1,将这个盘子从塔座A移动到塔座C*/
else
{
hanoi(one,three,two,n-1,num);/*将塔座A的前n-1个盘子移到塔座B*/
move(one,three,num);/*将塔座A的第n个盘子移到塔座C*/
hanoi(two,one,three,n-1,num); /*将塔座B的n-1个盘子移到塔座C*/
}
攀枝花学院学生课程设计论文 测试与运行
4 测试与运行
由需求分析可知,汉诺塔演示程序设计是在TC环境下利用递归算法实现大小不同的盘子移动的全过程演示。本程序已调试成功并实现了其功能,当移动盘块数为3时,其运行结果如下:
图4.1 盘块移动前
图4.2 盘块移动中
图4.3 盘块移动后
攀枝花学院学生课程设计论文 结束语
结束语
在这次课程设计中,我基本上完成了任务,通过递归调用算法实现了汉诺塔的演示过程,以及盘块移动的具体步骤的显示,基本上达到了此次课程设计的要求。但是它的不足也是显而易见的,在盘块移动的过程中用方向键移动时会一次显示两个步骤,这给用户的实际操作带来了一定的困难,所以这是值得改进的地方,整个程序的功能有待进一步完善,让更多的方法能得以实现。
虽然在这次的课程设计中有很多的不足,但是我也有很多的收获。上网查找资料,找到了一个基于TC对话框而实现的汉诺塔演示程序设计,于是我们就开始研究它的算法,如何画三个塔座,如何填充盘块的颜色,如何实现盘块的移动。再运用这些知识在TC中实现这次课程设计所要完成的任务。这让我不仅对TC开发环境有了更多的认识和了解,对其图形设备接口的知识也有了很好的掌握,而且让我对图形学的知识有了更好的运用,拓展了对图形学的知识了解的视野,让我的理论知识和算法有了更多的实践。作为一个大的项目,我更体会到了团队合作精神的重要性,虽然我的设计是一个人一组的,但我深刻地认识到只有大家一起努力地学习并研究相关的知识,才能提高做事的效率,也才能更好更快地完成任务。所以这将在我以后的学习和生活中有很在的引导作用。在以后的学习中,我也将加倍地学习图形学的有关知识,以同样的方法学习其他的知识,不断地丰富自己,充实自己,提高自己的能力。
参考文献
[1] Hearn(赫恩)Baker 著.计算机图形学== Computer Graphics:C语言版. 清华大学出版社,2004
[2] 陈桂芳. 微型计算机图形学. 北京理工大学出版社. 1989
[3] 陈元琰编著.计算机图形学实用技术.科学出版社.2000
[4] 柳朝阳,周晓平.计算机图形学:图形的计算与显示原理. 西安电子科技大学出版社 .2005
[5] 陆润民.C语言绘图教程.清华大学出版社.1996
[6] 陈锦昌,赵明秀.C语言计算机绘图教程.华南理工大学出版社.1998.9
[7] 杨昂岳.微机实用绘图方法与技巧.国防科技大学出版社.1995.12
展开阅读全文