C语言版科学计算器设计.docx

上传人:b****5 文档编号:30266341 上传时间:2023-08-13 格式:DOCX 页数:17 大小:62.63KB
下载 相关 举报
C语言版科学计算器设计.docx_第1页
第1页 / 共17页
C语言版科学计算器设计.docx_第2页
第2页 / 共17页
C语言版科学计算器设计.docx_第3页
第3页 / 共17页
C语言版科学计算器设计.docx_第4页
第4页 / 共17页
C语言版科学计算器设计.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

C语言版科学计算器设计.docx

《C语言版科学计算器设计.docx》由会员分享,可在线阅读,更多相关《C语言版科学计算器设计.docx(17页珍藏版)》请在冰豆网上搜索。

C语言版科学计算器设计.docx

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;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1