科学计算器设计.docx

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

科学计算器设计.docx

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

科学计算器设计.docx

科学计算器设计

科学计算器设计(C语言版)

学校:

学院:

计算机信息工程学院

语言

平台:

作者:

日期:

一、背景和目的

计算器是现代日常生活中使用较为频繁的工具之一,常用的计算器有简易版和科学计算器两种模式.简易版的计算器不支持表达式运算,每次只能输入一个数据或者运算符来计算,而科学计算器除了容纳简易版计算器的功能外,还支持表达式运算,用户可以输入一个合法的算术表达式来得到所需的结果。

常用的算术表达式有三种,前缀表达式,中缀表达式和后缀表达式。

中缀表达式:

我们平时书写的表达式就是中缀表达式,形如(a+b)*(c+d),事实上是运算表达式形成的树的中序遍历,特点是用括号来描述优先级。

后缀表达式:

也叫逆波兰表达式,事实上是算数表达式形成的树的后序遍历.中缀表达式(a+b)*(c+d)的后缀表达式是ab+cd+*,它的特点就是遇到运算符就立刻进行运算。

前缀表达式:

算数表达式形成的树的前序遍历。

日常所书写的是中缀表达式,但是计算机内部是用后缀表达式计算,所以此程序的用户使用中缀表达式作为输入,程序将中缀表达式转化为后缀表达式后再进行运算并输出结果。

由于今后工作将使用C语言进行开发,而C语言是一个功能强大并且很灵活的语言,为复习和巩固C编程,故决定用C语言编写一个科学计算器。

本次开发采用C语言,以面对过程思想进行开发,使用的数据结构有队列和栈。

二、模块设计

本次开发,使用的控制台输入,并直接在控制台输出。

科学计算器的功能组件如下:

中缀表达式转后缀表达式

trans_expr()

输入表达式

input_expr()

当读到数字直接送至输出队列中

当读到运算符T时

a:

将栈中所有优先级高于或等于T的运算符弹出,送至输出队列

b:

T进栈

读到左括号时总是将它压入栈中

读到右括号时,将靠近栈顶的第一个左括号上面的运算符依次全部弹出,送至输出队列,再丢弃左括号

计算后缀表达式

calcu_expr()

建立一个栈

从左到右读后缀表达式,读到数字就将它压入栈S中,读到运算符则从栈中依次弹出两个数X和Y,然后以“X运算符Y”的形式计算出结果,再将结果压入栈S

如果后缀表达式未读完,就重复上述过程,最后输出栈顶数值则为结束

输出结果

转换成功

Y

N

三、详细设计

宏:

#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

h〉

//#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〈s;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〈infixLen;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〈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;

returnerror;

//输出运算结果

voidshow(void)

inti,n;

#ifndefTEST

for(i=0;i〈suffixLen;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