C语言简易科学计算器源代码链栈的应用原创Word格式文档下载.docx
- 文档编号:16445496
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:11
- 大小:681.75KB
C语言简易科学计算器源代码链栈的应用原创Word格式文档下载.docx
《C语言简易科学计算器源代码链栈的应用原创Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《C语言简易科学计算器源代码链栈的应用原创Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。
}token;
struct{//expression,用来存储表达式
char*str;
intcur;
//标记读取expr的当前位置
}expr;
StackOPND,OPTR;
//操作数栈operand,运算符栈operator
intexpr_size;
//表达式长度
voidInitStack(Stack*S){//初始化栈
*S=(Stack)malloc(sizeof(SNode));
if(!
(*S)){
printf("
动态申请内存失败!
\n"
);
exit(0);
}//if
(*S)->
next=NULL;
}//InitStack
voidDestroyStack(Stack*S){//销毁栈
SNode*p;
while(p=*S){
*S=p->
next;
free(p);
}//while
}//DestroyStack
voidPush(StackS,SElemTypee){//入栈
p=(SNode*)malloc(sizeof(SNode));
p){
exit(0);
strcpy(p->
date.optr,e.optr);
p->
date.opnd=e.opnd;
date.flag=e.flag;
next=S->
S->
next=p;
}//Push
voidPop(StackS,SElemType*e){//出栈
p=S->
栈为空,不能出栈!
next=p->
strcpy(e->
optr,p->
date.optr);
e->
opnd=p->
date.opnd;
flag=p->
date.flag;
free(p);
}//Pop
voidget_expr(){//获取expr字符串
char*p;
intsize;
expr.cur=0;
expr_size=100;
expr.str=(char*)malloc(expr_size*sizeof(char));
expr.str){
内存分配失败!
size=0;
p=expr.str;
while((*p=getchar())!
='
\n'
){
if(*p!
'
if((*p>
A'
)&
&
(*p<
Z'
)){
*p=*p+32;
//将大写转换成小写
}//if
p++;
size++;
if(size==expr_size-1){//此时expr.str已满,将其扩大
expr_size+=EXPR_INCREMENT;
expr.str=(char*)realloc(expr.str,expr_size*sizeof(char));
if(!
printf("
exit(0);
}//if
p=&
expr.str[size];
//realloc后需重新指定p
}//if
*p++='
#'
;
*p='
\0'
}//get_expr
intIsOpnd(charch){//判断ch是否是操作数的一部分
if((ch>
0'
(ch<
9'
)||(ch=='
.'
return1;
if((ch=='
-'
+'
)){//如若+-前面是'
或'
('
则为正负号
if((expr.cur==0)||(expr.str[expr.cur-1]=='
return1;
return0;
}//IsOpnd
voidgettoken(){//获取一个标记
char*p=token.str;
*p=expr.str[expr.cur];
if(IsOpnd(*p)){
while(IsOpnd(*++p=expr.str[++expr.cur]));
//注意是分号结尾
*p='
token.type=0;
//将标记类型设定为操作数
return;
if((*p>
a'
z'
)){//接收sin,tan,ln之类的函数运算符或操作数
while((expr.str[expr.cur+1]>
(expr.str[expr.cur+1]<
*++p=expr.str[++expr.cur];
}//while
++expr.cur;
*++p='
strcmp(token.str,"
e"
)){//e为欧拉数,既自然对数的底数
sprintf(token.str,"
%.16g"
exp
(1));
//springf是库函数,功能是将显示在屏幕上的内容储存在字符串中
pi"
)){//pi为圆周率
//sprintf(token.str,"
strcpy(token.str,"
3.1415926535897932"
token.type=1;
//将标记类型设定为运算符
}//gettoken
charPrecede(SElemType*optr1,SElemType*optr2){//返回优先关系
char*str1,*str2;
str1=optr1->
optr;
str2=optr2->
strcmp(str1,"
ln"
)||!
lg"
sin"
cos"
tan"
optr1->
flag=1;
//这些均为单目运算符
return(!
strcmp(str2,"
("
^"
!
"
))?
<
'
:
>
return'
optr1->
flag=2;
switch(str1[0]){
case'
:
case'
return(!
+"
)||!
-"
)"
#"
*'
/'
*"
)||
!
/"
return!
)?
='
)'
return'
^'
}//switch
}//Precede
longfactorial(longn){//阶乘
return(n<
=1)?
1:
n*factorial(n-1);
}//factorial
SElemTypeOperate(SElemTypeopnd1,SElemTypeoptr,SElemTypeopnd2){//计算
SElemTypetemp;
if(optr.flag==1){
if(!
strcmp(optr.optr,"
))temp.opnd=factorial((long)opnd2.opnd);
elseif(!
))temp.opnd=log10(opnd2.opnd);
))temp.opnd=log(opnd2.opnd);
))temp.opnd=sin(opnd2.opnd);
))temp.opnd=cos(opnd2.opnd);
))temp.opnd=tan(opnd2.opnd);
returntemp;
switch(optr.optr[0]){
temp.opnd=opnd1.opnd+opnd2.opnd;
break;
temp.opnd=opnd1.opnd-opnd2.opnd;
temp.opnd=opnd1.opnd*opnd2.opnd;
temp.opnd=opnd1.opnd/opnd2.opnd;
temp.opnd=pow(opnd1.opnd,opnd2.opnd);
returntemp;
}//Operate
intmain(){
SElemTypeoptr,opnd1,opnd2;
printf("
\n欢迎使用简易科学计算器!
欧拉数为e,圆周率为pi,退出则输入quit!
优先级:
括号高于'
高于'
高于lg,ln,sin,cos,tan高于*,/高于+,-\n"
请输入计算表达式:
\n\n"
while
(1){
get_expr();
strcmp(expr.str,"
quit#"
return0;
InitStack(&
OPTR);
OPND);
strcpy(optr.optr,"
Push(OPTR,optr);
gettoken();
//从expr.str中获取一个标记(操作数或运算符)
while(strcmp(token.str,"
)||strcmp(OPTR->
next->
date.optr,"
if(token.type){//说明token存储的是运算符
strcpy(optr.optr,token.str);
switch(Precede(&
(OPTR->
date),&
optr)){
case'
//栈顶元素优先权低
strcpy(optr.optr,token.str);
Push(OPTR,optr);
gettoken();
break;
//脱括号并接收下一字符
Pop(OPTR,&
optr);
//退栈并将运算结果入栈
Pop(OPND,&
opnd2);
if(optr.flag==2){//是双目运算符才需另一个操作符
Pop(OPND,&
opnd1);
}//if
Push(OPND,Operate(opnd1,optr,opnd2));
}//switch
else{//说明token存储的是操作数
opnd1.opnd=atof(token.str);
Push(OPND,opnd1);
//atof将token.str转换为双精度数
gettoken();
//获取下一个标记
}//else
%.16g\n\n"
OPND->
date.opnd);
free(expr.str);
DestroyStack(&
free(expr.str);
}//main
//实例测试:
23.243*(5-(2-13/.23)/(2-9.235)-((4-20)/2)-32*(3+2.23/(2*3)))
//标准答案为:
-2380.7610725282693238114006817341
//实例测试2:
23.243*(5-(2!
-13/0.23)/(2!
-9.235)-((4!
-20)!
/2!
)-32*(3!
+2.23/(2*3)!
))
//答案:
-4802.8159654171577130910009145737
//实例测试3:
23.243*(5^(4+2!
)-(2!
^2-13/0.23)/(2^4!
^2!
336114.71943320758873596787452698
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 简易 科学 计算器 源代码 应用 原创