计算器实验报告
班级: 07计本(1)班
姓名: 王林
学号: 20706031047
指导老师: 韩静
一、 需求分析
(1) 制作一个计算器界面工程,有数字运算符等键,输入表达式后,按等号键输入结
束,并显示出正确的结果。
(2) 程序能根据运算符的高低进行运算
(3) 可以输入括号
二、 设计思路
(1) 用工程建立一个字符串的类结构,并用编辑框输入相应的数字和字符,并且
输入的字符用字符串逐个接受,当输入为’=’的时候,用‘#‘做最后一个输入。
(2) 开始对所输入的字符串进行运算和操作,显示在工程中的编辑框内。
(3) 如果结束则关闭,如果再次进行运算则进行清零。
三、 主程序段
char Precede(char a,char b) //判断优先级的函数 {
switch(a)
{
case'+':{if(b=='*'||b=='/'||b=='(') return('<');
else return('>');
}
case'-':{if(b=='*'||b=='/'||b=='(') return('<');
else return('>');
}
case'*':{if(b=='(') return('<');
else return('>');
}
case'/':{if(b=='(') return('<');
else return('>');
}
case'(':{if(b==')') return('=');
else if(b=='#') return('0');
else return('<');
}
case')':{if(b=='(') return('0');
else return('>');
}
case'#':{if(b==')') return('0');
else if(b=='#') return('=');
else return('<');
}
}
}
float Operate(float a,char theta,float b) //计算两个数的结果的函数 {
float z;
switch(theta){
case '+':z=a+b;break;
case '-':z=a-b;break;
case '*':z=a*b;break;
case '/':z=a/b;break;
}
return(z);
}
float Shuhe(SqStack1 &OP,int k,int j)
{
int i,e,n=k;
float sum=0,fe;
while(j!=0)
{
Pop1(OP,e);
fe=float(e);
for(i=1;i<=j;i++)
fe=fe/10;
sum=sum+fe;
j--;
}
while(k!=0)
{
Pop1(OP,e);
for(i=0;i<n-k;i++)
e=e*10;
sum=sum+e;
k--;
}
return(sum);
}
void CMyDlg::OnButton12()
{
UpdateData(TRUE);
m_ss=m_ss+'#';
SqStack OPTR;
SqStack1 OP; //输入的字符转化为数字的函数 //字符型栈的定义 //整型型栈的定义
SqStack2 OPND; //浮点型栈的定义 int i=0,flag=0,k=0,tag=0,j=0;
float sum,a,b;
char c,x,theta;
InitStack(OPTR); Push(OPTR,'#');
InitStack2(OPND);InitStack1(OP);
c=m_ss[i++];
while(c!='#'||GetTop(OPTR)!='#')
{
if(c=='.')
{
tag=1;c=m_ss[i++];
}
else if(c>='0'&&c<='9')
{
Push1(OP,int(c)-48);
c=m_ss[i++];
if(tag==0) k++;
else j++;
flag=1;
}
else
{
if(flag==1)
{
sum=Shuhe(OP,k,j);
Push2(OPND,sum);
OP.top=OP.base;
k=0;flag=0;j=0;tag=0;
}
switch(Precede(GetTop(OPTR),c))
{
case'<'://栈顶元素优先权低
{
Push(OPTR,c);c=m_ss[i++];
break;}
case'='://脱括号并接收下一个字符
{Pop(OPTR,x); c=m_ss[i++];
break;}
case'>'://退栈并将运算结果入栈
{Pop(OPTR,theta);
Pop2(OPND,b);Pop2(OPND,a);
Push2(OPND,Operate(a,theta,b));
break;}
}
}
}
sum=GetTop2(OPND);
m_ss.Format("%f",sum);
UpdateData(FALSE);
}
四、 调试分析
(1) 当输入“1+2-3=”时,显示结果为“0.000000”,结果正确,置清零。
(2) 当输入“2.96*1.85/6.741=”时,显示结果为“0.812342”, 结果正确,置清零。
(3) 当输入“2.69-19.145=”时,显示结果为“-16.455000”, 结果正确,置清零。
(4) 当输入“5-7*(5+1.8)=”时,显示结果为“-42.600002”, 结果正确,置清零。
(5) 当输入“2-/65=”时,显示结果为“1.969231”,结果错误,置清零。
(6) 当输入“-6+9=”时,显示结果为“-107374176.000000”, 结果错误,置清零。
(7) 当输入“0-6+9=”时,显示结果为“3.000000”, 结果正确,置清零。
(8) 当输入“(2+3)*5-8=”时,显示结果为“17.000000”, 结果正确,置清零。
(9) 当输入“6*(-3+1)=”时,显示结果为“12.000000”, 结果错误,置清零。
(10) 当输入“6*(0-3+1)=”时,显示结果为“-12.000000”, 结果正确,置清零。
(11) 当输入“6*(1-3)=”时,显示结果为“-12.000000”, 结果正确,结束。
调试说明以及分析:
1、当输入为正确的格式时,能算出正确的结果,其中包括:小数、整数以及个位以上的数字,且运算符包括:加、减、乘、除运算,还有就是可以加括号等。
2、当输入为错误的格式是,显示的是错误的结果,如(5)中的运算结果就是错误的。
3、若某个数字是负数,如果直接输入,结果是错误的,但如果变为零减去该数字的绝对值的话或者把两数的顺序更改一下,显示的是正确的结果,如
(6)、(7)、(9)、(10)、(11)做的结果。
4、有时候会出现一些不精确的显示结果,如(4)中显示多的是0.000002,这是由于在C语言的定义时,系统所产生的结果,与算法无关。
2008.12.25
第二篇:实验报告之计算器(单片机C语言)
计算器实验报
告目录
实验目的... 3
实验器材... 4
实验任务... 5
实验步骤... 6
1、在protues中画好原理图... 6
2、在keil中编写程序... 6
3、仿真... 8
4、程序清单... 8
实验小结... 15
实验目的
学习运用4*4的矩阵键盘,学会使用单片机编程扫描法
学习使用1602液晶显示,对其初始化
学习综合使用液晶、键盘,学会综合编程
实验器材
上机仿真
计算机一台
Keil软件
Protues软件
实验任务
运用at89s51和1602液晶与按键开关来制作简单的两位的加减乘除的简单计算器。
实验步骤
1、在protues中画好原理图
2、在keil中编写程序
编写过程
编译通过
3、仿真
4、程序清单
#include<reg51.h> //包含头文件
#define uc unsigned char //宏定义
sbit rs=P3^5; //位申明
sbit rw=P3^6;
sbit e=P3^7;
void csh(); //函数申明
void jj();
uc keyscan();
void wirte_com(uc com);
void wirte_data(uc date);
void delay(unsigned int z);
uc code table[]="123+456-789*0=#/"; //定义表格
uc code table1[]="0123456789";
uc code table2[]="2 wei ji suan qi";
uc temp,bb,num,a,b,c,d,shi,ge,bai,qi; //定义全局变量
unsigned int i;
void main() //主函数
{
csh(); //初始化
while(1) //大循环
{
for(i=0;i<16;i++)
{
wirte_data(table2[i]);
}
wirte_com(0xc0);
num=99;
keyscan();
a=table[num]-48;
wirte_data(table[num]);
num=99;
keyscan();
wirte_data(table[num]);
if(table[num]>=48&&table[num]<=57)
{
d=table[num]-48;
a=a*10+d;
num=99;
keyscan();
b=table[num];
wirte_data(b);
}
else
{
b=table[num];
}
num=99;
keyscan();
c=table[num]-48;
wirte_data(table[num]);
num=99;
keyscan();
if(table[num]>=48&&table[num]<=57)
{
wirte_data(table[num]);
d=table[num]-48;
c=c*10+d;
}
switch(b)
{
case '+':i=a+c;break;
case '-':jj();break;
case '*':i=a*c;break;
case '/':i=a/c;break;
default:break;
}
qi=i/1000;
bai=i%1000/100;
shi=i%100/10;
ge=i%10;
keyscan();
while(num!=13) keyscan();
wirte_data(table[13]);
if(qi!=0)
{
wirte_data(table1[qi]);
wirte_data(table1[bai]);
wirte_data(table1[shi]);
wirte_data(table1[ge]);
while(num!=14) keyscan();
wirte_com(0x01);
}
else if(bai!=0)
{
wirte_data(table1[bai]);
wirte_data(table1[shi]);
wirte_data(table1[ge]);
while(num!=14) keyscan();
wirte_com(0x01);
}
else if(shi!=0)
{
wirte_data(table1[shi]);
wirte_data(table1[ge]);
while(num!=14) keyscan();
wirte_com(0x01);
}
else
{
wirte_data(table1[ge]);
while(num!=14) keyscan();
wirte_com(0x01);
}
}
}
void jj()
{
if(a>c)
i=a-c;
else
i=c-a;
}
void csh() //初始化子函数
{
P3=0xff;
wirte_com(0x01);
delay(10);
wirte_com(0x38);
delay(10);
wirte_com(0x0f);
delay(10);
wirte_com(0x06);
delay(10);
wirte_com(0x80);
delay(10);
}
void wirte_com(uc com) //液晶写指令
{
P2=com;
rs=0;
rw=0;
e=0;
delay(10);
e=1;
}
void wirte_data(uc date) //液晶写数据
{
P2=date;
rs=1;
rw=0;
e=0;
delay(100);
e=1;
}
void delay(unsigned int z) //延时子程序
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uc keyscan() //键盘扫描子程序
{
while(1)
{
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
bb=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:num=0;break;
case 0xde:num=1;break;
case 0xbe:num=2;break;
case 0x7e:num=3;break;
default:break;
}
while(P1==bb);
delay(10);
while(P1==bb);
}
}
P1=0xfd;
temp=P1;
bb=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=4;break;
case 0xdd:num=5;break;
case 0xbd:num=6;break;
case 0x7d:num=7;break;
default:break;
}
while(P1==bb);
delay(10);
while(P1==bb);
}
}
P1=0xfb;
temp=P1;
bb=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=8;break;
case 0xdb:num=9;break;
case 0xbb:num=10;break;
case 0x7b:num=11;break;
default:break;
}
while(P1==bb);
delay(10);
while(P1==bb);
}
}
P1=0xf7;
temp=P1;
bb=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=12;break;
case 0xd7:num=13;break;
case 0xb7:num=14;break;
case 0x77:num=15;break;
default:break;
}
while(P1==bb);
delay(10);
while(P1==bb);
}
}
if(num!=99) return(num);
}
}
实验小结
通过本次实验我巩固了前面对键盘、液晶的使用,并且学会了如何把它们综合起来运用,更加熟悉了程序编写过程!