c语言课程设计简单计算器程序.docx
- 文档编号:29147691
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:21
- 大小:417.54KB
c语言课程设计简单计算器程序.docx
《c语言课程设计简单计算器程序.docx》由会员分享,可在线阅读,更多相关《c语言课程设计简单计算器程序.docx(21页珍藏版)》请在冰豆网上搜索。
c语言课程设计简单计算器程序
C语言课程设计简单计算器程序(总24页)
课程设计名称:
C语言课程设计
课程设计题目:
简单计算器程序
第1章需求分析
1.1设计要求
(1)用C语言数据结构实现程序设计;
(2)利用结构体、栈、进行相关信息处理;
(2)系统的各个功能模块要求用函数的形式实现;
(4)界面简单,可操作性高。
1.2任务
(1)定义一个结构体类型数组,输入0~9及+、--、*等符号的信息,将其信息存储起来;
(2)输入简单的加减乘除算术计算式,并在屏幕上显示逆波兰(后缀式)表达式和计算结果;
(3)编写代码;
(4)程序分析与调试。
说明:
本课程设计将实现一个简单计算器。
在功能上尽量模仿windows的计算器。
系统界面不做牵制要求。
该程序能实现标准型中+、-、*、/、(、)、.、的混合运算表达式(一般意义上的中缀表达式),将其转换成逆序波兰表达式(后缀表达式)并计算输出结果。
在进行运算后可以选择继续运算或者结束当前运算。
即时准确地获得需要的计算的结果,充分降低了数字计算的难度和节约了时间,对人们的生活有一定的帮助。
第2章总体设计
2.1设计简介及设计方案论述
逆波兰表达式又叫做后缀表达式。
在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,所以,这种表示法也称为中缀表达式。
波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法。
按此方法,每一运算符都置于其运算对象之后,故称为后缀表达式。
后缀表达式的优点是显而易见的,编译器在处理时候按照从左至右的顺序读取逆波兰表达式,遇到运算对象直接压入堆栈,遇到运算符就从堆栈提取后进的两个对象进行计算,这个过程正好符合了计算机计算的原理。
后缀表达式比前缀表达式更加易于转换,并且它的最左面一定为数字,这一点在实际编程的时候就会体会到它的好处了。
逆波兰表达式有一个更大的优点,就是拆括号,根据运算符的级别将中缀表达式转换成逆波兰表达式后,运算顺序就已经替代了运算符的级别,这样也避免了括号提高运算级别的特殊处理。
2.2功能模块层次图
将算术表达式转化为逆波兰表达式计算逆波兰表达式的值
第3章详细设计
3.1栈的定义与使用
首先定义两个栈,一个字符型,一个双精度型,程序代码如下:
Struct
{
chardata[MaxSize];//存放表达式的字符数组
inttop;//栈顶指针
}Sym;/*符号*///作为存放运算表达式的栈使用
struct
{
doubledata[MaxSize];//存放运算结果的数组
inttop;//栈顶指针
}Num;/*数*/存储逆波兰表达式(后缀式)计算器的运算数//作为存放运算结果的栈使用
voidInitStack()
{Sym.top=Num.top=-1;}//栈的初始化
voidSymPush()//压栈
{
if(Sym.top {Sym.data[++Sym.top]=calc[i++];} else {printf("Sym栈满\n");return;} } voidSymPop()//出栈 { if(Sym.top>=0) {expr[++t]=Sym.data[Sym.top--];} else {printf("Sym栈空\n");return;} } voidNumPush()//压栈 { If(Num.top { Num.data[++Num.top]=ston(expr,&i); } else { printf("Num栈满\n");return; } } 定义逆波兰(后缀式)表达式的计算函数(出栈) voidNumPop() { if(Num.top>=0) { if(expr[i]! ='') { switch(expr[i]) { case'+': Num.data[Num.top-1]=Num.data[Num.top-1]+Num.data[Num.top];break; case'-': Num.data[Num.top-1]=Num.data[Num.top-1]-Num.data[Num.top];break; case'*': Num.data[Num.top-1]=Num.data[Num.top-1]*Num.data[Num.top];break; case'/': Num.data[Num.top-1]=Num.data[Num.top-1]/Num.data[Num.top];break; } Num.top--; } } else {printf("Num栈空\n"} } 定义一个对逆波兰表达式中,数字的处理函数 doubleston(charx[],int*p) { intj=*p+1,i; doublen=0; charsign=x[*p]; if(sign=='+'||sign=='-') *p=*p+1; while(x[j]>='0'&&x[j]<='9') {j++;} for(i=*p;i {n=n*10+(x[i]-'0');} if(x[j]=='.') { *p=++j; while(x[j]>='0'&&x[j]<='9') { j++; } for(i=*p;i {n=n+pow(0.1,i-*p+1)*(x[i]-'0');} } *p=j; if(sign=='-') return(-n); return(n); } 3.2功能模块流程图(以下有简易图与详细图) 3.3由(后缀)逆波兰表达式计算中缀表达式原理 计算机处理(后缀)逆波兰表达式求值问题是比较方便的,即将遇到的操作数暂存于一个操作数栈中,凡是遇到操作数,便从栈中pop出两个操作数,并将结果存于操作数栈中,直到对(后缀)逆波兰表达式中最后一个操作数处理完,最后压入栈中的数就是后最表达式的计算结果。 中缀表达式转换为等价的(后缀)逆波兰表达式,中缀表达式不方便与计算机处理,通常要讲中缀表达式转换为一个与之等价的(后缀)逆波兰表达式。 等价是指两个表达式的计算顺序和计算结果完全相同。 中缀表达式: 0.3/(5*2+1)=的等价(后缀)逆波兰表达式是: 0.352*1+/=仔细观察这两个等价的表达式可知,操作数的出现次序是相同的,但运算符的出现次序是不同的。 在(后缀)逆波兰表达式中,运算符的出现次序是实际进行操作的次序;在中追表达式中,由于受到操作符的优先级和括号的影响,操作符出现次序与实际进行操作的次序很可能是不一样的。 3.3.1算法描述 将中缀表达式转换为等价的(后缀)逆波兰表达式的过程要使用一个栈放“(”,具体可以按照下面的方式进行。 (1)从左到右一次扫描中缀表达式的每一个字符,如果是数字字符和圆点“.”则直接将它们写入(后缀)逆波兰表达式中。 (2)如果遇到的是开括号“(”,则将它们压入一个操作符栈(不需要与栈顶操作符相比较),它表明一个新的计算层次的开始,在遇到和它匹配的闭括号“)”时,将栈中的元素弹出来并放入(后缀)逆波兰表达式中,直到栈顶元素为“(”时,将栈顶元素“(”弹出(不需要加入(后缀)逆波兰表达式),表明这一层括号内的操作处理完毕。 (3)如果遇到的是操作符,则将该操作符和操作符栈顶元素比较: a当所遇到的操作符的优先级小于或等于栈顶元素的优先级时,则取出栈顶元素放入(后缀)逆波兰表达式,并弹出该栈顶元素,反复执行直到栈顶元素的优先级小于当前操作符的优先级;b、当所遇到的操作符的优先级大于栈顶元素的优先级的时则将它压入栈中。 (4)重复上述步骤直到遇到中缀表达式的结束符标记“=”,弹出栈中的所有元素并放入(后缀)逆波兰表达式中,转换结束。 第4章调试分析 4.1程序设计中所遇到的错误及犯错的原因 (1)在编辑程序时,往往需要输入汉字作为提示信息,而此时,忘记切换输入法,导致用搜狗输入法输进去的字符使得程序无法编译成功。 (2)在编辑程序时,将关键字输入错误,如: else打成else,printf打成print......... (3)调试程序时,运行界面还未关闭,有点击运行,致使程序无法运行。 (4)清屏函数不会使用。 (5)运行程序之后,输入时,因输入法的问题可能会出现运算错误。 4.2错误的解决方法 (1)先找到错误出现的大概区域,然后仔细盘查,最终发现问题所在。 (2)解决方法同上。 (3)请教同学,在同学的指导下解决了此错误。 (4)用手机上网XX搜索并请教同学,从而解决了问题。 (5)进行多次调试后发现问题所在,并独立解决。 第5章用户手册 5.1对于此“计算器程序”,操作简单方便,能快速算出您所需的计算结果。 5.2开始时,进入运行界面,根据程序运行提示进行输入, 如图所示: 图5.1 要输入正常运算表达式,如: 12*23—34/15*(26.5+3.4)= 注意: 在输入表达式时,切记使用电脑原自带输入法,不要使用搜狗等输入法,否则程序可能无法正确读取字符,从而使运算结果出错! 如图所示: 图5.2 输入之后请按回车键,之后程序便自动会将表达式转化为逆波兰表达式(后缀式),并输出计算结果! 如图所示: 图5.3 继续计算请输入y,退出请输入n。 如图所示: 输入y的显示界面 图5.4 输入n的显示界面 切记: 运行程序时,请客户务必按照程序运行提示,进行一系列的相关操作,否则,程序可能会运行出错,所以,请用户谨慎操作! 总结 经过了两个多星期的C语言程序设计,终于在老师的细心指导和同学的热情帮助下基本完成了计算器课题的设计任务! 虽然有些地方不尽如人意但是初步达到了对自己的要求! 刚开始设计的时候找不到头绪,不知道该从哪里下手! 通过向同学询问和查找资料找走进了设计的门槛! 通过网上查找到很多成功的计算器程序,通过对那些已经成功地程序进行分析找到自己的设计思路,制定设计流程。 并通过比较各种程序了解各个程序的利弊,从而明确自己计算器的设计方向和如何通过技术手段达到自己的目的! 万事开头难,可是对于并不是很熟悉的C语言数据结构的我,在一开始的设计中,困难重重,.通过查找C语言数据结构的教材,去图书馆查找相关的资料和同学一起讨论终于把一个个棘手的陌生的问题解决! 程序编好后,在测试阶段中发现了几处错误导致程序不能运行,通过耐心的分析源代码终于编好了一个完整无误的程序。 参考文献 [1]C程序设计(第三版)谭浩强清华大学出版社2012年1月 [2]数据结构(c语言版)杨薇薇清华大学出版社2011年 [3]数据结构精讲与习题详解殷人昆清华大学出版社2012年 [4]数据结构殷人昆清华大学出版社2012年 [5]c语言课程设计案例精编郭翠英中国水利出版社2004.03 [6]c程序设计语言克尼汉,徐宝文2004.01.01 附录(程序清单) #include #include #include #include #include #defineMaxSize99 charcalc[MaxSize],expr[MaxSize]; inti,t; struct { chardata[MaxSize]; inttop; }Sym; struct { doubledata[MaxSize]; inttop; }Num; doubleston(charx[],int*p) { intj=*p+1,i; doublen=0; charsign=x[*p]; if(sign=='+'||sign=='-') *p=*p+1; while(x[j]>='0'&&x[j]<='9') {j++;} for(i=*p;i {n=n*10+(x[i]-'0');} if(x[j]=='.') { *p=++j; while(x[j]>='0'&&x[j]<='9') { j++; } for(i=*p;i {n=n+pow(0.1,i-*p+1)*(x[i]-'0');} } *p=j; if(sign=='-') return(-n); return(n); } voidInitStack() {Sym.top=Num.top=-1;} voidSymPush() { if(Sym.top {Sym.data[++Sym.top]=calc[i++];} else {printf("Sym栈满\n");return;} } voidSymPop() { if(Sym.top>=0) {expr[++t]=Sym.data[Sym.top--];} else {printf("Sym栈空\n");return;} } voidNumPush() { if(Num.top {Num.data[++Num.top]=ston(expr,&i);} else {printf("Num栈满\n");return;} } voidNumPop() { if(Num.top>=0) { if(expr[i]! ='') { switch(expr[i]) { case'+': Num.data[Num.top-1]=Num.data[Num.top-1]+Num.data[Num.top];break;case'-': Num.data[Num.top-1]=Num.data[Num.top-1]-Num.data[Num.top];break;case'*': Num.data[Num.top-1]=Num.data[Num.top-1]*Num.data[Num.top];break; case'/': Num.data[Num.top-1]=Num.data[Num.top-1]/Num.data[Num.top];break; } Num.top--; } } else {printf("Num栈空\n");return;} } intmain(void) { loop1: i=0,t=-1; system("cls"); printf("Calculator计算器\n"); printf("***************************************\n"); printf("*欢迎使用Welcome! : *\n"); printf("***************************************\n"); printf("请输入算术表达式(中缀表达式): \n"); InitStack(); gets(calc); while(calc[i]! ='\0'&&calc[i]! ='=') { if(calc[i]>='0'&&calc[i]<='9') { while((calc[i]>='0'&&calc[i]<='9')||(calc[i]=='.')) { loop2: expr[++t]=calc[i++]; } expr[++t]=''; } elseif(calc[i]=='(') {SymPush();} elseif(calc[i]==')') { while(Sym.data[Sym.top]! ='(') {SymPop();expr[++t]='';} Sym.data[Sym.top--]='\0'; i++; } elseif(calc[i]=='+'||calc[i]=='-') { if((i==0)||(! (calc[i-1]>='0'&&calc[i-1]<='9')&&calc[i-1]! =')')) gotoloop2; while(Sym.top>=0&&Sym.data[Sym.top]! ='(') {SymPop();expr[++t]='';} SymPush(); } elseif(calc[i]=='*'||calc[i]=='/') { while(Sym.top>=0&&(Sym.data[Sym.top]=='*'||Sym.data[Sym.top]=='/')) { SymPop(); expr[++t]=''; } SymPush(); } else{i++;} } while(Sym.top>=0) {SymPop();expr[++t]='';} expr[++t]=Sym.data[++Sym.top]=''; printf("\n"); printf("***************************************\n"); printf("逆波兰表达式(后缀表达式): \n%s=\n",expr); for(i=0;expr[i]! ='';i++) { If(expr[i]>='0'&&expr[i]<='9') {NumPush();} else{NumPop();} } printf("\n"); printf("运算结果为: \n%g\n",Num.data[0]); printf("***************************************\n"); printf("ContinueinputyExitinputn\n"); printf("继续输入计算y退出n\n"); switch(getch()) { case'y': {system("cls");gotoloop1;} case'n': default: exit(0); } getch(); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 课程设计 简单 计算器 程序