#C语言版科学计算器设计.docx
- 文档编号:24261100
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:17
- 大小:62.56KB
#C语言版科学计算器设计.docx
《#C语言版科学计算器设计.docx》由会员分享,可在线阅读,更多相关《#C语言版科学计算器设计.docx(17页珍藏版)》请在冰豆网上搜索。
#C语言版科学计算器设计
科学计算器设计(C语言版)
学校:
学院:
计算机信息工程学院
语言
平台:
作者:
日期:
一、背景和目的
计算器是现代日常生活中使用较为频繁的工具之一,常用的计算器有简易版和科学计算器两种模式。
简易版的计算器不支持表达式运算,每次只能输入一个数据或者运算符来计算,而科学计算器除了容纳简易版计算器的功能外,还支持表达式运算,用户可以输入一个合法的算术表达式来得到所需的结果。
常用的算术表达式有三种,前缀表达式,中缀表达式和后缀表达式。
中缀表达式:
我们平时书写的表达式就是中缀表达式,形如(a+b)*(c+d),事实上是运算表达式形成的树的中序遍历,特点是用括号来描述优先级。
后缀表达式:
也叫逆波兰表达式,事实上是算数表达式形成的树的后序遍历。
中缀表达式(a+b)*(c+d)的后缀表达式是ab+cd+*,它的特点就是遇到运算符就立刻进行运算。
前缀表达式:
算数表达式形成的树的前序遍历。
日常所书写的是中缀表达式,但是计算机内部是用后缀表达式计算,所以此程序的用户使用中缀表达式作为输入,程序将中缀表达式转化为后缀表达式后再进行运算并输出结果。
由于今后工作将使用C语言进行开发,而C语言是一个功能强大并且很灵活的语言,为复习和巩固C编程,故决定用C语言编写一个科学计算器。
本次开发采用C语言,以面对过程思想进行开发,使用的数据结构有队列和栈。
二、模块设计
本次开发,使用的控制台输入,并直接在控制台输出。
科学计算器的功能组件如下:
三、详细设计
宏:
#defineTEST//表示测试阶段
#defineMAX_SIZE100//表达式长度
#defineLBRACKET0//左括号
#defineRBRACKET1//右括号
#defineADD2//加
#defineSUB3//减
#defineMUL4//乘
#defineDIV5//乘
#defineINT6//整数
#defineDOUBLE7//浮点数
数据结构:
表达式节点
structExprNode{
intn;//表达式节点类型
doublep;//表达式节点数据
};
中缀表达式:
structExprNodeinfixExpr[MAX_SIZE];
intinfixLen;
后缀表达式:
structExprNodesuffixExpr[MAX_SIZE];
intsuffixLen;
后缀转换栈:
inttransStack[MAX_SIZE];
inttransTop;
后缀表达式运算栈:
structExprNodecalcuStack[MAX_SIZE];
intcalcuTop;
函数过程:
__inlineintget_char(char*c)
缓冲变量无字符则读入字符
读入成功返回0,否者返回-1
intinput_expr(void)
读入表达式
若输入非法字符则返回-1,否则返回0
intpri(inta,intb)
优先级计算
若a优先于b则返回-1,否则返回0
inttrans_expr(void)
中缀表达式转换为后缀表达式
括号不匹配返回-1,否则返回0
__inlineintmaxn(inta,intb)
求最大值
structExprNodecalcu(structExprNode*a,structExprNode*b,intc)
计算a和b做c运算的结果
intcalcu_expr(void)
计算后缀表达式
表达式计算失败返回-1,否则为0
voidshow(void)
输出运算结果
代码:
#include
//#defineTEST//表示测试阶段
#defineMAX_SIZE100//表达式长度
#defineLBRACKET0//左括号
#defineRBRACKET1//右括号
#defineADD2//加
#defineSUB3//减
#defineMUL4//乘
#defineDIV5//乘
#defineINT6//整数
#defineDOUBLE7//浮点数
structExprNode{
intn;//表达式节点类型
doublep;//表达式节点数据
};
structExprNodeinfixExpr[MAX_SIZE];//中缀表达式
intinfixLen;
structExprNodesuffixExpr[MAX_SIZE];//后缀表达式
intsuffixLen;
inttransStack[MAX_SIZE];//后缀转换栈
inttransTop;
structExprNodecalcuStack[MAX_SIZE];//后缀表达式运算栈
intcalcuTop;
//缓冲变量无字符则读入字符
//读入成功返回0,否者返回-1
__inlineintget_char(char*c)
{
if(*c=='\0')returnscanf("%c",c);
return0;
}
//读入表达式
//若输入非法字符则返回-1,否则返回0
intinput_expr(void)
{
charc=0;
intflag=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;
caseMUL:
caseDIV:
p[i]=2;break;
}
}
if(p[0]>=p[1])
{
return-1;
}
return0;
}
//中缀表达式转换为后缀表达式
//括号不匹配返回-1,否则返回0
inttrans_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; } elseif(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; returnb; } //计算a和b做c运算的结果 structExprNodecalcu(structExprNode*a,structExprNode*b,intc) { structExprNoder; inti,j; r.n=maxn(a->n,b->n); switch(c) { caseADD: r.p=(a->p)+(b->p);break; caseSUB: r.p=(a->p)-(b->p);break; caseMUL: r.p=(a->p)*(b->p);break; caseDIV: 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; structExprNodea[2],r; calcuTop=0; for(i=0;i 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; returnerror; } //输出运算结果 voidshow(void) { inti,n; #ifndefTEST for(i=0;i { switch(infixExpr[i].n) { caseLBRACKET: printf("(");break; caseRBRACKET: printf(")");break; caseADD: printf("+");break; caseSUB: printf("-");break; caseMUL: printf("*");break; caseDIV: printf("/");break; caseINT: 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); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言版 科学 计算器 设计