《小型计算器》Word文档文档格式.docx
- 文档编号:20749630
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:13
- 大小:44.43KB
《小型计算器》Word文档文档格式.docx
《《小型计算器》Word文档文档格式.docx》由会员分享,可在线阅读,更多相关《《小型计算器》Word文档文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
2012、3、20设备编号:
同组人员:
指导教员签字:
成绩:
教员评语:
一、实验名称
编写模拟小型计算器功能的程序。
二、实验目的
1.掌握栈的应用。
2.掌握“拼数”技术。
3.掌握字符串处理方法。
三、实验内容和要求
(1)完成对正整数的加减乘除运算,不进行错误检查。
输入一个数,一个运算符和另一个数,按=键和Enter键。
输出计算结果。
例如,输入:
123+305=
按Enter键后,输出计算结果。
(2)完成正整数的混合四则运算,要考虑优先级,但算式中不带括号,程序不作错误检查。
12+34*54-21/3=
(3)完成实数的混合四则运算,不作错误检查。
(4)完成带括号的混合四则运算,不作错误检查。
12*(2+4)/5=
(5)完成带负数,带数学函数的混合四则运算。
-12.3+sin(0.12)=
这一层主要练习如何处理负数和函数等“一目”运算。
(6)完成带错误检查的.用于任一数学表达式的计算。
当检查到错误时.最好指明错误的位置和出错原因。
例如,在第5个字符处少右括号、或少运算符、多运算符、数值中出现字母等非数值字符。
四、实验环境
1.硬件环境:
PC机
2.软件环境:
Windows操作系统,VC++集成开发环境
五、算法设计思想
题目的第一级即一个简单的整数拼数函数,所以程序主要问题是从第二级开始的。
模拟人脑的进行正整数四则运算的过程,设计者发现,运算符的运算优先次序与栈的“后进先出”特点是相切合的,所以整个程序是建立在栈结构的基础之上的。
但是,运算式是由数字和和运算符构成的,所以建立了一个数栈(num)一个符号栈(symb)。
当扫描指针扫描到数时,调用拼数函数,然后将得到的数字进入数栈;
反之扫描到符号时,则需调用优先级比较函数(judge),比较符号栈顶的符号和扫描到的符号的优先级。
若后者优先级大于前者,则扫描到的运算符入栈,扫描指针后移;
如果栈顶元素优先级高于扫描到的函数,则调用计算函数(count)进行计算。
Count函数将弹出符号栈中的栈顶元素和数栈的两个元素,然后两者进行弹出的运算符所对应的计算。
得到的结果存入数栈,然后扫描指针后移。
当符号栈中的元素为空并且扫描指针指向“=”号时,输出结果。
第二级运算实现。
第三级只是将前一级中的拼数函数进行了补充修改,用以实现实数的拼数问题。
这里就不加赘述了。
第四级是要求完成带括号的运算。
设计者对括号进行了以下条件限制:
●左括号直接入栈;
●左、右括号优先级均比一般运算符(+、-、*、/、^)低;
●扫描指针为右括号并且符号栈栈顶元素为左括号时,左括号出栈,扫描指针后移。
通过这三条即可使得括号里面的内容先进行计算。
第五级要求实现负数、sin()等一目运算。
当扫描到字母时,调用转换函数(change2),将输入的字母字符串和负号转换为对应的单个字符运算符(这样便于judge函数的判断和count函数的计算)。
然后根据具体运算先后次序补充judge函数优先级,补充count函数。
即实现了一目运算。
六、主要问题与解决方法
(一)当程序刚调试完成时,整个程序代码很混乱,if语句的嵌套过多。
其中单单求解函数(result)长度就多达130行,使人阅读起来非常的不方便。
于是,设计者根据需要,将拼数函数、字符串转换函数、优先级比较函数和计算函数单独提取了出来,并且加上了一些必要的备注,增加了程序的可读性,便于日后查看修改。
(二)实现第二级时,当第一个符号入栈时,符号栈为空,无法做优先级比较。
所以设计者一开始便在符号栈的栈底填入了一个“#”,其优先级最低。
输入字符串
sin
cos
tan
负号(-)
对应运算符
s
c
t
f
(三)当扫描指针读取到sin的时候,实际上是读到的s、i、n单个字符,于是编写了change2函数,以实现类似于拼数函数的功能。
一开始设计者考虑的是用字符数组的结构,通过指针扫描的方式实现,但在实际编写过程中发现这样做过于复杂且问题太多,考虑到数学函数名较短的特点,便直接采用了条件结构if加&
&
符号的方式实现。
对应关系如下:
(四)为了方便用户连续计算,于是在主函数里面加入了选择循环的指令,使用户使用更加方便。
七、实验结果
程序实现了题目第一到五级的要求,运算结果保留两位小数。
以下是实际运算界面的截图:
第一级
第二级
第三级
第四级
第五级
第六级查错(不完全)
而对于题目的第六级,目前设计者的思路是编写一个检查函数(check),然后根据运算式的合法规则,对原字符数组进行检查。
但由于需要考虑的问题很多,所以暂时没有能够实现。
八、体会、质疑、建议
通过这次小型计算器程序的编写,我对栈的概念有了更深的认识,特别是对于栈独特的结构特点有了进一步的认识。
而刚拿到实验题目的时候,我只有一些片段性的思路,然而需要考虑的问题却太多,使得自己一时间无从下手。
后来,根据题目的步步深入,一级一级的实现,发现问题竟变得简单了许多。
这也给了我一个启示:
以后面对问题时,要学会将问题分块、分步骤的思考解决,或许会更加容易。
另外,这是个程序也是我们所遇到过的比较复杂的一个程序,这个程序的完成,使得自己更有信心完成后续的课程。
最后,还有一个小插曲。
由于前一份实验报告因为系统还原丢失了,需要手工输入的字又比较多,所以我就想找一个可以识别图片上的文字的软件。
到XX上查了一下,竟然还专门有这样一门名叫0CR光学字符识别的技术。
下载了相关软件后,我将课本上的文字用数码相机照了下来,然后运行了软件,将其成功的转化成了电子稿。
这也算我做这个实验一个收获吧!
九、源代码
.cpp文件连接
/***********************************************************/
/*本程序可继续添加单目和双目的运算如arcsin(),arccos()等等*/
#include<
stdio.h>
string.h>
malloc.h>
math.h>
#defineN100//多项式的字符长度
#defineSUCC1
#defineFAIL0
unsignedm=50;
//栈的初始长度
unsigneddelta=10;
//栈的追加长度
typedefchareletype1;
typedefeletype1*eptr1;
typedefdoubleeletype2;
typedefeletype2*eptr2;
eptr1p1;
eptr2p2;
voidnumpush(eptr2&
p2,eptr2&
top2,eletype2x)//数栈进栈函数
//p2为数栈的起始指针
//top2为数栈栈顶指针
//x为进栈的数
{if(top2==p2+m)
{m+=delta;
p2=(eptr2)realloc(p2,m*sizeof(eletype2));
top2=p2+m-delta;
}
top2++;
*top2=x;
intnumpop(eptr2&
top2,eletype2&
x)//数栈出栈函数
//x用来记录出栈的数
{
if(top2==p2)returnFAIL;
x=*top2;
top2--;
returnSUCC;
voidsymbpush(eptr1&
p1,eptr1&
top1,eletype1x)//符号栈进栈函数
//p1为字符栈的起始指针
//top1为字符栈栈顶指针
//x为进栈的字符
{if(top1==p1+m)
p1=(eptr1)realloc(p1,m*sizeof(eletype1));
top1=p1+m-delta;
++top1;
*top1=x;
intsymbpop(eptr1&
top1,eletype1&
x)//符号栈出栈函数
//x用来记录出栈的字符
if(top1==p1)returnFAIL;
x=*top1;
top1--;
intjudge(charp,chara)//存优先级表以及做优先级比较的函数
{
eletype1symb[]={'
+'
'
-'
j'
s'
c'
t'
*'
/'
^'
='
#'
('
)'
};
intfirst[]={2,2,3,4,4,4,5,5,6,0,-1,1,1};
inti=0,j=0;
while(a!
=symb[i])i++;
while(p!
=symb[j])j++;
if(first[i]>
first[j])return(SUCC);
elsereturn(FAIL);
}
voidchange(eletype1a[],int&
i,eletype2&
q)//拼数函数
{eletype2r=0,r1=1;
q=0;
while(a[i]>
0'
a[i]<
9'
)//拼整数部分
{q=q*10+a[i]-'
;
i++;
if(a[i]=='
.'
)
{i++;
)//拼小数部分
{r1=r1*0.1;
r=r+(a[i]-'
)*r1;
i++;
q=q+r;
voidchange2(eletype1a[],int&
i,eletype1&
w)
//单目运算返回字符的转换
{i=i+1;
w='
elseif(a[i]=='
a[i+1]=='
i'
a[i+2]=='
n'
{i=i+3;
o'
a'
intcheck(eletype1str[])//查错函数(不完全)
{
inti=0,l=0,r=0;
while(str[i])
if(str[i]=='
l++;
elseif(str[i]=='
)//左右括号数目限制
r++;
elseif(str[i-1]>
str[i-1]<
i!
=0&
str[i+1]>
str[i+1]<
//字符中出现非法字符
{if(str[i]!
str[i]!
!
(str[i]>
str[i]<
))
{printf("
第%d个字符位置出现非法字符。
\n"
i+1);
return0;
}}
if(l<
r){printf("
缺少一个左括号\n"
);
elseif(l>
缺少一个右括号\n"
return1;
eletype2count(eptr1&
top1,eptr2&
top2)//计算函数,包括单目运算和双目运算
{eletype1w;
eletype2y,z;
symbpop(p1,top1,w);
switch(w)
case'
:
numpop(p2,top2,z);
numpop(p2,top2,y);
z=y+z;
break;
z=y-z;
z=y*z;
z=y/z;
z=pow(y,z);
z=-z;
z=sin(z);
z=tan(z);
z=cos(z);
default:
printf("
error!
return(z);
voidresult(eletype1a[])
eptr1p1,top1;
eptr2p2,top2;
inti=0;
eletype1w;
eletype2z=0,q;
top1=p1=(eptr1)malloc(m*sizeof(eletype1));
top2=p2=(eptr2)malloc(m*sizeof(eletype2));
*top1='
*top2=NULL;
while(a[i])
{
/***********************数字的处理**************************/
if(a[i]>
{change(a,i,q);
numpush(p2,top2,q);
//实数进栈
q=0;
/************************符号的处理**************************/
if(*top1=='
a[i]=='
){printf("
%7.2f\n"
*top2);
elseif((a[i]>
z'
||a[i]=='
)&
(i==0||!
(a[i-1]>
a[i-1]<
||a[i-1]=='
)))
{change2(a,i,w);
symbpush(p1,top1,w);
elseif(*top1=='
)//左右括号相遇,则消去栈中的左括号
{symbpop(p1,top1,w);
i++;
elseif(a[i]=='
)//左括号直接进栈
{symbpush(p1,top1,a[i]);
elseif(judge(*top1,a[i]))//判断优先级,比栈顶元素大进栈,反之栈顶出栈
{
symbpush(p1,top1,a[i]);
}
/*********************************************************/
else
{z=count(p1,top1,p2,top2);
numpush(p2,top2,z);
}
}
voidmain()
inti,a;
eletype1str[N];
本计算器可执行包括+,-,*,/,^,sin(),cos(),tan()的多步科学计算。
\n结果保留两位小数。
do
{printf("
请输入计算式:
scanf("
%s"
str);
//输入表达式
if(check(str))
result(str);
//求解函数
for(i=0;
\0'
i++)
str[i]='
printf("
是否继续计算?
1、是;
2、否\n"
%d"
&
a);
}while(a==1);
谢谢使用,再见!
(注:
素材和资料部分来自网络,供参考。
请预览后才下载,期待你的好评与关注!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 小型计算器 小型 计算器 Word 文档
![提示](https://static.bdocx.com/images/bang_tan.gif)