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

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

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

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

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

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;

}

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

当前位置:首页 > 高中教育 > 数学

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

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