目录
1 基本功能描述... 1
2 设计思路... 1
3 软件设计... 4
3.1 设计步骤... 4
3.2 界面设计... 5
3.3 关键功能的实现... 11
4 结论与心得体会... 12
5 附录... 14
5.1 调试报告... 14
5.2 测试结果... 15
5.3 关键源代码... 16
1 基本功能描述
简单计算器包括双目运算和单目运算功能。双目运算符包含基本的四则运算及乘幂功能,单目运算符包含正余弦,阶乘,对数,开方,倒数等运算。可对输入任意操作数,包括小数和整数及正数和负数进行以上的所有运算并能连续运算。出现错误会给出相应提示,同时包含清除,退格,退出功能以及有与所有按钮相对应的菜单项。
2 设计思路
如图是整个计算器的流程图,打开计算器程序,输入数据,调用输入数据子程序。子程序开始时m_num为零。按下数字按钮后,判断m_num的正负号,对其进行相关处理,然后在判断是否有小数点,处理后输出结果。
回到总流程图中,输完第一个操作数后,若按下双目运算符,则把m_num存入num1,按下输入第二个操作数并算出结果。若按下的是单目运算符,则直接对其处理得出结果。若按下清零,则m_num等于0.在运算中还要判断运算是否合法,以及结果是否超出显示范围,以做出相关提示,按下清零。算出后把结果保存至num1。若需用算出的结果继续运算则回到输入完第一个操作数后,若不需要则判断试否需要开始新一轮的运算,不需要则结束。
图1 输入数据子函数流程图突起
图2 简单计算器总流程图
3 软件设计
3.1 设计步骤
打开Microsoft Visual Studio2010,在文件中点击新建,在弹出框内选择MFC 应用程序工程,输入工程名Calculate及其所在位置,点击确定,如图3所示。
图3 新建MFC应用程序工程
这样在MFC应用程序下建立了一个基于对话窗口的程序框架,如图4所示。
图4 新建的对话框
3.2 界面设计
1、创建控件
在图4所示的在资源视图选项卡中打开Calculate资源组,双击IDD_Calculate_DIALOG,在右边的窗口中显示出待编辑的对话框。开始摆放控件,包括编辑框和按钮的创建。
表1 各按钮和编辑框等对象的属性
完成后界面如图5所示。
图5 计算器界面
2、连接变量和代码
1) 给编辑框连接变量。在编辑框上单击鼠标右键,在弹出菜单中选择ClassWizard菜单项,弹出MFC ClassWizard对话框,选择成员变量选项卡,如图6所示。
图6 MFC类向导对话框中的成员变量选项卡
在选择 ID列表框中选择IDC_EDIT1,单击添加变量按钮,在弹出的对话框中连接变量m_num。变量类型设定为doubel型。
3.3 关键功能的实现
1)操作数的输入
编辑框所关联的变量为m_num,程序开始时为零。每按下一个数字键按钮,就把它累加到m_num里并刷新显示。整型变量xsd来判断是否有小数点和一个double型xsw来表示小数点后的数据的位数。当xsd=0时,表示无小数点,否则则表示有小数点。按下小数点按钮后执行xsd=1。当按下一个数字键时,首先判断m_numd的正负,再根据xsd判断是否按下小数点,若有则把小数点后数的位数xsw*0.1,将键入的数除以xsw然后正数累加,负数累减到编辑框所关联的变量m_num上,若没有则把m_num乘以10,然后累加或累减到编辑框所关联的变量m_num上。
2)单目运算符功能的实现
由于单目运算符中必须有执行运算的函数,因而头文件中要加入math.h,如m_num=sqrt(m_num).按下按钮即可实现其功能。
3)双目运算符功能的实现
双目运算符需要两个操作数才能运算,所以在执行双目运算符按钮的函数代码中,要把m_num中的值保存到变量num1中,然后把m_num清零。这样即可保存第一个操作数。另外先定义了一个整形变量cal,在不同的双目运算符中给cal赋不同的值,然后在等号中用switch语句来匹配cal值来判断需要执行何种双目运算。
4)退格键功能的实现
当按下一次退格按钮时,若m_num为整数,只需对其中数据除以10再取整(floor()和ceil()函数)即可,若按下一次退格按钮为小数,则根据小数点后数据的位数xsw进行操作,先对xsw乘以10,然后被m_num除取整,接着与xsw相乘即可。
4 结论与心得体会
经过多番测试,得出结论为设计的计算器能够完成功能描述内容中的全部功能。
正所谓“纸上谈兵终觉浅,觉知此事要躬行。”所以在本学期课程设计是很及时、很必要的。这样不仅能加深我们对MFC程序设计的掌握,而且还及时、真正的做到了学以致用。主要是以下几点。
基本功要过硬。不能马虎经常犯犯小错误。提高自己找错纠错能力,通常错误总是那几种,多练习就熟练了。
要善于查找资料提高自己的资料查询能力,要善于利用网络来获得知识,获得帮助。开始着手程序设计时,有些功能感觉无从下手,都不知道要干什么。这些问题只要找到相关的资料就会得到提示从而理解所要解决问题的大致方向。有了明确的目的,就可以发挥自己的头脑来完成它了。
要善于思考。程序中有些实现难点和最初完成程序时免不了的许多不足就需要自己根据代码认真思考来解决。只有这样才能纠正程序的不足并使其更加人性化。
5编程中的困难及解决方法
描述等号对应的消息处理函数中需要处理的问题及相应的实现代码?
答:在双目运算符按钮函数代码中将整形变量cal赋值,然后在等号中用switch语句来匹配cal值来判断需要执行何种双目运算 ,保存结果便于下次计算和一些变量的清零。实现代码见6.3。
怎样在编辑框中实现中文字提示?
经网上查找,使用SetWindowText("XXXXXXX");可以实现该功能,但是经过多次尝试,却总是出现如下的错误:
经过多次查找资料和尝试最终发现需要一个转换的操作就是在用_T()进行转换。如上GetDlgItem(IDC_EDIT1)->SetWindowText(_T("结果过大,无法显示"));
就可以了!
6 附录
6.1 调试报告
6.2 测试结果
1.输入“90.5”,“-”,“60.7”,“=”,“+”,“2.36”,“ =”,,得到结果如图7。
图7结果图1
2.输入“0”,“ln”,结果如图2
图7结果图2
证明错误提示功能实现正常。
6.3 关键源代码
1、 数字键0的程序:
void CCalculateDlg::OnClickedButton10()
{
{if (m_num>=0)
{
if(xsd==0)
m_num=m_num*10+0;
else
{
m_num=m_num+xsw*0;
xsw*=0.1;
}
UpdateData(false);
}
else
{
if(xsd==0)
m_num=m_num*10-0;
else
{
m_num=m_num-xsw*0;
xsw*=0.1;
}
UpdateData(false);
}
}
}
2、 加法键+的程序:(-,*,/,x,x^y的代码类似)
void CCalculateDlg::OnBnClickedplus()
{
cal=1;
num1=m_num;
m_num=0;
xsd=0;
xsw=1.0;
}
3、 = 键的程序:
void CCalculateDlg::OnBnClickedequal()
{
switch (cal)
{
case 1:
m_num=m_num+num1;
UpdateData(false); //数ºy据Y刷¡é新?
break;
case 2:
m_num=num1-m_num; //两¢?数ºy相¨¤减?
UpdateData(false); //数ºy据Y刷¡é新?
break;
case 3:
m_num=num1*m_num; //两¢?数ºy相¨¤乘?
if(m_num>=1.7e308||m_num<-1.7e308)
GetDlgItem(IDC_EDIT1)->SetWindowText(_T("结果太大,无法显示!"));
UpdateData(false); //数ºy据Y刷¡é新?
break;
case 4:
if (m_num==0) //在¨²除y法¤¡§中D,ê?判D断?除y数ºy是º?否¤?为a0
GetDlgItem(IDC_EDIT1)->SetWindowText(_T("错误,0不能作除数”));
else
{
m_num=num1/m_num;
UpdateData(false);
}
break;
case 5:
m_num=pow(num1,m_num);
if(m_num>=1.7e308||m_num<-1.7e308)
GetDlgItem(IDC_EDIT1)->SetWindowText(_T("结果太大,无法显示!"));
UpdateData(FALSE);
break;
}
xsw=1.0;
xsd=0;
cal=0;
}
4、n!键的程序:
void CCalculateDlg::OnBnClickedfactorial()
{
int i;
if (xsd==0)
{
for (i=m_num;i>0;i--)
m_num*=i;
}
else
GetDlgItem(IDC_EDIT1)->SetWindowText(_T("整?数ºy才?能¨¹进?行D阶¡Á乘?运?算?!ê?"));
if(m_num>=1.7e308||m_num<-1.7e308)
GetDlgItem(IDC_EDIT1)->SetWindowText(_T("结¨¢果?太¬?大䨮,ê?无T法¤¡§显?示º?"));
else
UpdateData(FALSE);
xsd=0;
xsw=1.0;
}
5、Dele键的程序:
void CCalculateDlg::OnBnClickeddelete()
{
if (xsd==0)
{
if (m_num<0)
m_num=ceil(m_num/10);
else
m_num=floor(m_num/10);
UpdateData(false);
}
else if(xsd==1)
{
if (xsw==0.1)
{
if (m_num<0)
m_num=ceil(m_num);
else
m_num=floor(m_num);
UpdateData(false);
xsw*=10.0;
xsd=0;
}
else
{
xsw=xsw*10.0;
if (m_num<0)
m_num=xsw*ceil(m_num/xsw);
else
m_num=xsw*floor(m_num/xsw);
UpdateData(false);
}
}
}
第二篇:计算机综合实践报告
四川大学网络教育学院
实践课程报告 实践课程计算机综合实践报告 校外学习中心 成都职业技术学院 专业电气工程及其自动化 层 次 2010春季 年 级曾仲凡
学生姓名 杨宏杰 学号DH110158002
20xx年 3 月 12 日
实验一DEBUG调试工具熟悉、使用
一、 实验题目:熟悉、使用DEBUG调试工具
二、 实验日期:20xx年4月22日
三、 实验目的
1、 了解并逐步熟悉汇编语言的编辑方式及特点
2、 复习8088汇编语言的段结构、常用的指令与伪指令、存
储空间的分配等
3、 掌握汇编语言的编辑、汇编及连接过程
4、 了解并逐步掌握运用DEBUG进行调试汇编语言程序
5、 借助DEBUG调试工具来发现汇编语言程序的错误所在并
加以改正
四、 实验内容
1、进入DEBUG
方法1:在Windows开始菜单中单击运行命令,直接在运行对话框中输入“DEBUG”
方法2:在运行对话框中输出“CMD”启动DOS命令窗口后输入“DEBUG”
方法3:在程序、附件、命令提示符,启动DOS命令窗口后输入“DEBUG”
2、DEBUG命令格式
DEBUG的每个命令都是一个字母后跟一个或多个参数,
下面对DEBUG命令作几点说明:
(1)字母部分大小写
(2)只使用16进制数,且不能带后缀H
(3)以空格或逗号作为命令各项之间的分隔符。分隔符只
在两个数值之间是必须的
(4)可以用Ctrl-C或Ctrl-Break终止命令执行
(5)若输入的命令有语法错误,则提示“Error”,并用“^”
指出错误位置
3、常用的Debug功能
用Debug的R命令查看、改变CPU寄存器的内容;
用Debug的D命令查看内存中的内容
用Debug的E命令改写内存中的内容
用Debug的U命令将内存中的机器指令翻译成汇编指令
用Debug的T命令执行一条机器指令
用Debug的A命令以汇编指令的格式在内存中写了一条机器指令
4、用Debug的R命令查看、改变CPU寄存器的内容
R命令用来显示和修改寄存器的值,包括以下两种格式。
(1) R
显示所有寄存器和8个标志位的值,并反汇编CS:IP所
指的指令
(2) R(寄存器名)
显示指定寄存器的值,并等待用户键入新的值,按回车
键结束R命令
5、用Debug的D命令查看内存中的内容
D命令可以查看内存中的内容,D命令的格式较多,只
介绍本次实验中用到的格式,8086/8088CPU能够访问1M内容,D命令可以显示0000:0000H-FFFF:FFFFH中的任何一个单元的内存
如果想知道内存100000H处的内容,可以用“d段地址:偏移地址”
的格式来查看,如输入
-d 1000:0
使用d 1000:9查看1000:9处的内容
使用d 1000:0 9查看1000:0—1000:9的内容
一进入Debug,可直接使用D命令直接查看,将列出Debug预设的地
址处的内容
6、用Debug的E命令改写内存中的内容
使用“e起始地址数据数据数据……”的格式来进行
如将内存1000:0-1000:9单元中的内容分别改写为0、1、2、
3、4、5、6、7、8、9
-e 1000:0 0 1 2 3 4 5 6 7 8 9
也可采用提问方式一个一个修改内存中的内容,如
输出e 1000:0按Enter键输入修改的数据,在按空格键输入下
一个要修改的数据,最后Enter键结束操作
输入字符串的格式:如-e 1000:10 1 ‘a’2”c++”3”IBM”将
输入1 a 2 c++ 3 IBM到相应单元
向内容中写入机器码,如b80100(代表mov ax 0001),b90200
(代表mov cx 002),01c8(代表 add ax cx),那么输入-e 1000:0 b8 01 00 b9 02 00 01 c8就将该程序输入内容1000:0处,然后使用u命令-u 1000:0可以将内存单元中的内容翻译成汇编指令。如果要执行该程序,首先用r命令,单步执行程序。执行T命令时,CPU执行CS:IP执行的指令并将IP加1
7、用Debug的A命令以汇编指令的形式在内存中写了机指令 示列:用A命令,输入下列程序并运行
-a 1000:0
mov ax, 1
movbx, 2
mov cx, 3
add ax, bx
add ax, cx
add ax, ax
直接按Enter键结果输入。用r命令将cs修改成1000,ip修改成0,再执行t命令,单步执行程序。执行T命令时,CPU执行CS:IP执行的指令并将IP加1.
实验二设计汇编语言程序
一、 实验题目:设计汇编语言程序
二、 实验日期:20xx年4月28日
三、 实验目的:
字符串统计程序设计
双字乘法程序设计
四、 实验内容
1、 字符串统计
在数据段中建立一个缓冲区BUFFER,变量VER,编程使得程序具有如下功能:从键盘输入一个子字符串存入VER,从键盘输入包含一个或几个字符串的字符串存入BUFFER。统计BUFFER中的字符串含有多少个子字符串以及每个子字符串的位置
2、 双字乘法程序
设计一个程序实现32位带符号双精度数乘法运算。由于只有8位和16位的乘法指令。因此32位乘法运算是不能直接用指令实现的。但可以用16位乘法指令,通过4次想乘然后把部分积想加。对于带符号数,可以先根据绝对值求得积。然后判断积的符号,若积为负数,应将其用补码表示
五、 程序设计
1、 字符串统计程序设计
#include<iostream>
using namespace std
int main
char a;int b=0,c=0,e=0,f=0
cout<<“请输入一行任意字符:”
a=cin. get()
while(a!=’/n’)
if(a<0∥a>128)
b++
else if (a>=’a’&&a<=’z’∥a>A’&&a<=’Z’)
c++
else if(a==’‘)
d++
else if(a>=’0’&&a<’9’)
e++
else f++
a=cin.get()
cout<<“总共有”<<b/2+c+d+e+f<<“个字符:”<<enf1\ cout<<“中文”<<“/t”<<“英文”<<“/t”<<“空格”
<<“/t”<<“数字”<<“/t”<<“其他”<<end1
cout<<b/2<<”/t”<<c<<”/t”<<d<<”/t”<<e<<”/t”<<f<<end11
return 0
分别统计出英文字母,空格,数字和其他字符的个数
2、 双字乘法程序设计
Data segment
Xdw 1,2;被乘数
Ydw 3,4;乘数
Zdw 4 dup (?);积
Data ends
Code segment
Assume ds;data,cs:code
Start:
Movax,data
Movds,ax
Mul y
Movz,ax
Mov z+2,dx
Mov ax,x+2
Mul y
Mov z+4,ax Mov z+6,dx Movax,x Mov y+2 Add z+4,ax Add z+6,ax Mov ax,x+2 Mul y+2 Adc z+8,ax Adc z+10,dx Adc z+12,0 Mov ax,4c00h Int 21h Code ends End start
实验三 8253定时器、计数器接口与数字电
子琴
一、 实验题目:8253定时器、计数器接口与数字电子琴
二、 实验日期:20xx年5月3日
三、 实验目的:
改变定时器2的计数值来改变声音频率,通过编程来获得声调(频率)和节奏(延时长短),使计算机演奏出乐曲来。
四、 实验内容
设计程序让微机演奏一段简单乐曲
利用DOS的键盘管理功能,将微机变为一个具有简单功能的电子琴(选作)
五、 程序设计
硬件设计
利用实验板上的8253计数/定时器和8255并行接口,定时器8253利用工作方式3产生一定频率信号,通过可编程的并行外围接口芯片8255控制频率信号的通断。
8255的A口设置为输出,8255的A口的低两位用来控制扬声器驱动,当输出端口的PA0位为“1”或为“0”时,将使控制驱动器的与门电路接通或关闭,使8253所发出的音频信号能到达驱动器或被阻断。这样通过控制PA0的变化,可使扬声器接通和断开,就能发出不同的音长。8255的PA1位为“1”时,控制8253定时器产生驱动
扬声器发生的音频信号,该位为“0”则不发信号,8253有三个定时器,分别为0号、1号和2号定时器,驱动扬声器的是0号定时器,该定时器工作方式3,是一个频率发生器,它负责向扬声器发送指定频率的脉冲信号。当8255的PA0和PA1都为1时,8253发出之地呢频率的声音信号的前提下,声音信号通过与门到达驱动器驱动扬声器发声。
软件设计
系统要求实现2个功能,电子琴和音乐和的功能。两者发声的方法一样,只是一个数据从键盘读取,另一个是已经保存好的数据。首先我们可以用一个程序实现单个音调的产生,对8253输入不同的计数初值生成不同频率的波形,然后延时一段实践。电子琴程序主要是读取键盘按键,根据键值产生不同的音调即可。而乐曲的播放先将乐曲的音符编码表和节拍编码表建立好的,然后在播放时读取数据。
1、 单音调子程序SOUND
单音调子程序的调用前需要进行一下几个方面工作:
(1)确定相应的音调所对应的频率,查表可以得到,再由频率得到对应的8253计数初值
(2)确定音长,即一个音符所持续的时间。
在单音调子程序中实现发出一个音符的声音,持续所需的时间,流程如下:
→读取8253计数初值和音长→8253置初值→开启与门和
8253GATE→延时→关闭与门和8253GATE→返回
2、 音乐盒程序
音乐盒的乐曲播放程序中需要有两组数据支持:一组是频率数据,一组是节拍时间数据。音符的频率可以用过简谱从频率表中查得、节拍时间就是音符的持续时间,取决于乐曲的速度和每个音符的节拍数据。如4/4(四四拍)中,每小节包括4拍,全音符持续4拍,二分音符持续2拍,四分音符持续1拍,八分音符持续半拍等。
有了音调与频率和实践的关系后,就可以按照乐曲的曲谱将每个音符的频率和持续的时间定义成两组数据表,然后编程依次取出表中的频率值和节拍值,调用单音调子程序就可依次产生各个音调,播放出乐曲。
在程序中存储几个乐曲数据,根据音乐盒子菜单选择相应的乐曲演奏,读取对应的数据输出。