C语言版科学计算器设计.docx
- 文档编号:4317200
- 上传时间:2022-11-29
- 格式:DOCX
- 页数:16
- 大小:68.48KB
C语言版科学计算器设计.docx
《C语言版科学计算器设计.docx》由会员分享,可在线阅读,更多相关《C语言版科学计算器设计.docx(16页珍藏版)》请在冰豆网上搜索。
C语言版科学计算器设计
科学计算器设计(C语言版)
学校:
学院:
计算机信息工程学院
语言
平台:
作者:
日期:
一、背景和目的
计算器是现代日常生活中使用较为频繁的工具之一,常用的计算器有简易版和科学计算器两种模式。
简易版的计算器不支持表达式运算,每次只能输入一个数据或者运算符来计算,而科学计算器除了容纳简易版计算器的功能外,还支持表达式运算,用户可以输入一个合法的算术表达式来得到所需的结果。
常用的算术表达式有三种,前缀表达式,中缀表达式和后缀表达式。
中缀表达式:
我们平时书写的表达式就是中缀表达式,形如(a+b)*(c+d),事实上是运算表达式形成的树的中序遍历,特点是用括号来描述优先级。
后缀表达式:
也叫逆波兰表达式,事实上是算数表达式形成的树的后序遍历。
中缀表达式(a+b)*(c+d)的后缀表达式是ab+cd+*,它的特点就是遇到运算符就立刻进行运算。
前缀表达式:
算数表达式形成的树的前序遍历。
日常所书写的是中缀表达式,但是计算机内部是用后缀表达式计算,所以此程序的用户使用中缀表达式作为输入,程序将中缀表达式转化为后缀表达式后再进行运算并输出结果。
由于今后工作将使用C语言进行开发,而C语言是一个功能强大并且很灵活的语言,为复习和巩固C编程,故决定用C语言编写一个科学计算器。
本次开发采用C语言,以面对过程思想进行开发,使用的数据结构有队列和栈。
二、模块设计
本次开发,使用的控制台输入,并直接在控制台输出。
科学计算器的功能组件如下:
三、详细设计
宏:
#defineTESTﻩﻩﻩ//表示测试阶段
#defineMAX_SIZE 100//表达式长度
#defineLBRACKET0ﻩﻩ//左括号
#define RBRACKET1ﻩ//右括号
#defineADD2ﻩﻩ//加
#define SUB 3ﻩ//减
#defineMUL4ﻩ//乘
#define DIV5ﻩ//乘
#defineINT6ﻩﻩ//整数
#defineDOUBLE7ﻩﻩ//浮点数
数据结构:
表达式节点
structExprNode{
intn;ﻩ//表达式节点类型
doublep;ﻩ//表达式节点数据
};
中缀表达式:
structExprNodeinfixExpr[MAX_SIZE];
intinfixLen;
后缀表达式:
structExprNodesuffixExpr[MAX_SIZE];
intsuffixLen;
后缀转换栈:
inttransStack[MAX_SIZE];
inttransTop;
后缀表达式运算栈:
structExprNode calcuStack[MAX_SIZE];
intcalcuTop;
函数过程:
__inlineintget_char( char*c)
缓冲变量无字符则读入字符
读入成功返回0,否者返回-1
intinput_expr(void)
读入表达式
若输入非法字符则返回-1,否则返回0
intpri(int a,intb)
优先级计算
若a优先于b则返回-1,否则返回0
inttrans_expr(void)
中缀表达式转换为后缀表达式
括号不匹配返回-1,否则返回0
__inline int maxn(inta, intb )
求最大值
structExprNode calcu(structExprNode*a,struct ExprNode*b,intc )
计算a和b做c运算的结果
int calcu_expr(void)
计算后缀表达式
表达式计算失败返回-1,否则为0
ﻩ
voidshow(void)
输出运算结果
代码:
#include<stdio.h>
//#defineTESTﻩ//表示测试阶段
#defineMAX_SIZE100ﻩ//表达式长度
#defineLBRACKET0ﻩ//左括号
#defineRBRACKET 1ﻩ//右括号
#defineADD2ﻩﻩﻩ//加
#defineSUB 3ﻩ//减
#define MUL4ﻩ//乘
#define DIV5ﻩﻩ//乘
#defineINT 6ﻩﻩ//整数
#define DOUBLE 7ﻩ//浮点数
structExprNode{
intn;ﻩ//表达式节点类型
ﻩdoublep;ﻩ//表达式节点数据
};
structExprNodeinfixExpr[MAX_SIZE];//中缀表达式
intinfixLen;
structExprNodesuffixExpr[MAX_SIZE];ﻩ//后缀表达式
intsuffixLen;
inttransStack[MAX_SIZE];ﻩﻩ//后缀转换栈
inttransTop;
struct ExprNode calcuStack[MAX_SIZE];//后缀表达式运算栈
intcalcuTop;
//缓冲变量无字符则读入字符
//读入成功返回0,否者返回-1
__inlineintget_char(char *c)
{
if (*c=='\0')returnscanf("%c",c);
return0;
}
//读入表达式
//若输入非法字符则返回-1,否则返回0
intinput_expr(void )
{
ﻩchar c=0;
int flag= 0,error=0,s,i;
ﻩinfixLen =0;
ﻩwhile(get_char(&c)!
=-1)
ﻩ{
switch(c)
ﻩ{
ﻩcase'\n':
flag=-1;break;
case'(':
infixExpr[infixLen++].n = LBRACKET;c =0;break;
ﻩﻩcase')':
infixExpr[infixLen++].n=RBRACKET;c= 0; break;
case '+':
infixExpr[infixLen++].n=ADD;c=0; break;
ﻩcase'-':
infixExpr[infixLen++].n =SUB;c=0;break;
case'*':
infixExpr[infixLen++].n= MUL;c= 0; break;
ﻩcase'/':
infixExpr[infixLen++].n= DIV;c= 0;break;
ﻩﻩdefault:
ﻩif(c >='0'&&c<='9'||c=='.')
{
if (c!
='.')
ﻩﻩ{
ﻩﻩinfixExpr[infixLen].n=INT;
ﻩinfixExpr[infixLen].p=c-'0';
ﻩﻩs= 0;
ﻩﻩ}
ﻩﻩﻩelse
{
ﻩinfixExpr[infixLen].n= DOUBLE;
ﻩﻩﻩinfixExpr[infixLen].p=0;
ﻩﻩﻩs=1;
ﻩ}
ﻩc=0;
ﻩﻩwhile(get_char(&c)!
=-1)
ﻩﻩﻩ{
ﻩif(c >='0' &&c<='9')
ﻩﻩﻩ{
ﻩﻩﻩﻩﻩinfixExpr[infixLen].p=infixExpr[infixLen].p*10+(c-'0');
ﻩﻩﻩﻩif (s )s++;
ﻩc= 0;
ﻩﻩﻩﻩ}
elseif(c=='.')
ﻩ{
ﻩﻩif(s)
ﻩﻩﻩﻩﻩ{
ﻩﻩerror = -1;
ﻩﻩ}
ﻩﻩﻩﻩelse
ﻩﻩ{
ﻩﻩﻩinfixExpr[infixLen].n =DOUBLE;
ﻩﻩs++;
ﻩﻩﻩﻩﻩ}
ﻩﻩﻩc= 0;
ﻩﻩﻩ}
ﻩﻩelsebreak;
ﻩﻩ}
ﻩﻩﻩif(infixExpr[infixLen].n==DOUBLE)
ﻩﻩ{
ﻩfor(i=1; i
ﻩ{
ﻩﻩﻩinfixExpr[infixLen].p/=10;
ﻩﻩ}
ﻩﻩﻩ}
ﻩinfixLen++;
ﻩﻩﻩ}
ﻩﻩelse
ﻩﻩ{
ﻩﻩﻩerror=-1;
ﻩc=0;
ﻩ}
ﻩﻩbreak;
ﻩ}
ﻩif( flag)break;
};
ﻩreturnerror;
}
//优先级计算
//若a优先于b则返回-1,否则返回0
intpri( inta,intb)
{
ﻩintc[2],p[2],i;
c[0]=a;c[1]=b;
ﻩfor (i =0;i <2;i++)
ﻩ{
ﻩswitch(c[i])
ﻩ{
ﻩcaseLBRACKET:
p[i]=0; break;
ﻩcaseADD:
ﻩcaseSUB:
p[i]=1; break;
case MUL:
ﻩcaseDIV:
p[i] =2; break;
ﻩﻩ
ﻩﻩ}
ﻩ}
ﻩif( p[0]>= p[1])
{
ﻩreturn-1;
ﻩ}
ﻩreturn0;
}
//中缀表达式转换为后缀表达式
//括号不匹配返回-1,否则返回0
int trans_expr(void)
{
inti, error=0,flag;
ﻩsuffixLen=0;
transTop =0;
ﻩfor ( i =0;i { ﻩif(infixExpr[i].n>= INT)ﻩ//当读到数字直接送至输出队列中 ﻩ{ ﻩsuffixExpr[suffixLen++]= infixExpr[i]; ﻩﻩ} ﻩﻩelseif(infixExpr[i].n >RBRACKET )//当读入运算符时 ﻩﻩ{ ﻩ//将栈中所有优先级高于或等于T的运算符弹出,送至输出队列 while(transTop>0 ) ﻩ{ ﻩif(pri(transStack[transTop-1],infixExpr[i].n )) ﻩﻩ{ ﻩﻩsuffixExpr[suffixLen++].n=transStack[--transTop]; ﻩ} ﻩﻩﻩelsebreak; } ﻩﻩ//再把运算符入栈 ﻩﻩﻩtransStack[transTop++]=infixExpr[i].n; ﻩ} else if(infixExpr[i].n==LBRACKET)ﻩ//读到左括号时总是将它压入栈中 ﻩ{ ﻩﻩﻩtransStack[transTop++] =infixExpr[i].n; ﻩ} ﻩﻩelseﻩ//读到右括号时 ﻩ{ ﻩﻩﻩflag= -1; ﻩﻩ//将靠近栈顶的第一个左括号上面的运算符依次全部弹出,送至输出队列 ﻩﻩﻩwhile(transTop > 0 ) ﻩﻩ{ ﻩﻩif( transStack[transTop-1]==LBRACKET ) ﻩﻩ{ ﻩflag=0; ﻩbreak; ﻩﻩﻩ} suffixExpr[suffixLen++].n=transStack[--transTop]; ﻩﻩ} ﻩﻩﻩ//再丢弃左括号 ﻩﻩif ( flag)error =-1; ﻩﻩelsetransTop--; ﻩ} ﻩ} ﻩwhile( transTop>0) ﻩ{ if(transStack[transTop-1]==LBRACKET ) ﻩ{ ﻩerror= -1; ﻩ} suffixExpr[suffixLen++].n =transStack[--transTop]; ﻩ} ﻩ //在测试阶段输出后缀表达式 #ifdefTEST ﻩfor(i=0;i ﻩ{ ﻩﻩswitch( suffixExpr[i].n) ﻩ{ ﻩcaseADD: printf("+ ");break; ﻩcaseSUB: printf("-");break; caseMUL: printf( "*"); break; ﻩcaseDIV: printf("/"); break; ﻩcaseINT: flag=suffixExpr[i].p;printf("%d",flag);break; ﻩcaseDOUBLE: printf( "%lf",suffixExpr[i].p );break; } } #endif ﻩreturnerror; } //求最大值 __inlineintmaxn( inta,intb) { ﻩif(a>=b)returna; ﻩreturn b; } //计算a和b做c运算的结果 structExprNodecalcu( structExprNode*a, structExprNode*b,intc) { structExprNoder; int i,j; r.n=maxn(a->n,b->n); ﻩswitch ( c) ﻩ{ caseADD: r.p= (a->p)+(b->p); break; ﻩcase SUB: r.p=(a->p)-(b->p);break; caseMUL: r.p= (a->p)*(b->p);break; case DIV: r.p=(a->p)/(b->p); ﻩﻩﻩ if(r.n==INT) ﻩ{ ﻩﻩﻩﻩ i= a->p; ﻩj=b->p; ﻩﻩif(i%j)r.n=DOUBLE; ﻩ} break; } returnr; } //计算后缀表达式 //表达式计算失败返回-1,否则为0 intcalcu_expr( void) { inti,j,error=0; struct ExprNodea[2],r; ﻩcalcuTop =0; for(i= 0;i< suffixLen&& ! error;i++) ﻩ{ if(suffixExpr[i].n>=INT )//读到数字就将它压入栈S中 ﻩ{ ﻩﻩcalcuStack[calcuTop++] = suffixExpr[i]; ﻩ} ﻩelse//读到运算符 ﻩﻩ{ ﻩﻩ//从栈中依次弹出两个数X和Y ﻩfor (j= 0;j < 2;j++) ﻩﻩ{ ﻩﻩﻩif (calcuTop) a[j]= calcuStack[--calcuTop]; elseerror=-1; ﻩ} //以"X运算符Y"的形式计算出结果,再将结果压入栈S if (! error) ﻩﻩ{ ﻩﻩcalcuStack[calcuTop++] =calcu(&a[1],&a[0], suffixExpr[i].n ); ﻩﻩ} ﻩ} ﻩ} if(calcuTop! =1) error=-1; ﻩreturn error; } //输出运算结果 voidshow(void ) { ﻩint i,n; #ifndefTEST ﻩfor( i=0; i ﻩ{ ﻩswitch(infixExpr[i].n) ﻩ{ ﻩcaseLBRACKET: printf( "( ");break; ﻩcase RBRACKET: printf( ")"); break; ﻩcase ADD: printf("+");break; ﻩcaseSUB: printf( "- ");break; ﻩﻩcaseMUL: printf("* "); break; ﻩcaseDIV: printf( "/"); break; case INT: n =infixExpr[i].p;printf("%d ", n);break; caseDOUBLE: printf("%lf",infixExpr[i].p); break; ﻩ} } #endif if(calcuStack[0].n==INT) { ﻩn =calcuStack[0].p; printf("=%d\n",n ); ﻩ} ﻩelse ﻩ{ printf("=%lf\n", calcuStack[0].p); } } intmain(intargc,charargv[]) { do ﻩ{ ﻩif(input_expr()) { ﻩprintf("请输入正确的表达式! \n"); ﻩﻩﻩcontinue; ﻩ} ﻩﻩif(trans_expr()! = -1&&calcu_expr()! = -1) ﻩ{ ﻩﻩshow(); ﻩ} else ﻩ{ ﻩﻩﻩprintf("请输入正确的表达式! \n" ); ﻩ} }while(1); return 0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言版 科学 计算器 设计
![提示](https://static.bdocx.com/images/bang_tan.gif)