我写了个计算器的程序(还未完善所有功能!),遇到点问题,主要是计算结果(有时对有时错)
我查了很久,也未果!故请版主们来看一下,谢啦!
程序如下:
#define MAX 100 #include<stdio.h> #include<stdlib.h> #include<math.h> typedef struct { float value;//数值 char charc[5];//运算符 }link;//结构体用于存放处理后的表达式(即是数值与运算符的集合) float operS(float c)//求一个数的开方 { float temp; temp=sqrt(c); return(temp); }
int operA(int a,int b)//求排列 { int i,sn; sn=1; for(i=a;i>=a-b+1;i--) sn=sn*i; return(sn); }
int operC(int a,int b)//求组合 { int temp,i,sn,tn; sn=1; for(i=a;i>=a-b+1;i--) sn=sn*i; tn=1; for(i=b;i>0;i--) tn=tn*i; temp=sn/tn; return(temp); }
int operX(int a,int b)//求a的b次方 { int i,sn=1; for(i=1;i<=b;i++) sn=sn*a; return(sn); }
int operN(int a)//求阶乘 { int i,sn; sn=1; for(i=a;i>0;i--) sn=sn*i; return(sn); }
calculation(link exp[],int k)//计算求值 { int i,j,t; for(i=1;i<=k;i++) for(j=1;exp[i].charc[j]!='#';j++)//即是后缀表达式中数值后面跟有运算符的就求值 switch(exp[i].charc[j]) { case'+':for(t=i-1;exp[t].value!=0&&t>0;t--)//向前看第一个exp[t].value不为0的值 { exp[i].value=exp[t].value+exp[i].value; exp[t].value=0;//计算之后便把它置0,新值保留在exp[i].value中 break; } case'-':for(t=i-1;exp[t].value!=0&&t>0;t--)//四则计算 { exp[i].value=exp[t].value-exp[i].value; exp[t].value=0; break; } case'*':for(t=i-1;exp[t].value!=0&&t>0;t--) { exp[i].value=exp[t].value*exp[i].value; exp[t].value=0; break; } case'/':for(t=i-1;exp[t].value!=0&&t>0;t--) { exp[i].value=exp[t].value/exp[i].value; exp[t].value=0; break; } } printf("表达式的值为:\n"); printf("%f",exp[k].value); }
void turn()//将表达式转换成后缀表达式,在这一过程中还求出了S(),A(),C()等的值 { int i,j,k,t,top,num,temp,sum1,sum2; float sum,su,tem; char expr[MAX],stack[MAX];//expr[]内放初始表达式,stack[]用作符号栈 link exp[MAX]; i=0;k=0;t=0;top=1;//k为表达式所含数值个数 printf("请输入要求值的表达式:\n"); do { i++; scanf("%c",&expr[i]); }while(expr[i]!='#'&&i<=MAX);//输入表达式 num=i; printf("原表达式为:\n"); for(i=1;i<=num;i++) printf("%c",expr[i]); printf("\n"); i=1; while(expr[i]!='#') { switch(expr[i]) { case'S':sum=0.0;su=0.0;tem=0.1;//是求S()的 i=i+2; while(expr[i]>='0'&&expr[i]<='9')//可能是小数 { sum=sum*10+expr[i]-48; i++; } if(expr[i]=='.') { i++; while(expr[i]>='0'&&expr[i]<='9') { su=su+(expr[i]-48)*tem; tem=tem*(0.1); i++; } } i++; sum=sum+su; exp[++k].value =operS(sum);//放入exp[]中 sum=0.0;su=0.0;//重新置0 break; case'A':sum1=0;sum2=0;t1=0;t2=0;//是求排列的 for(i=i+2;expr[i]!=',';i++)//前一个数 { t1++; sum1=sum1*10+expr[i]-48;; } for(i=i+1;expr[i]!=')';i++)//后一个数 { t2++; sum2=sum2*10+expr[i]-48; } i++; exp[++k].value=operA(sum1,sum2);//求值并保存 break; case'C':sum1=0;sum2=0;t1=0;t2=0;//求组合 for(i=i+2;expr[i]!=',';i++)//前一个数 { t1++; sum1=sum1*10+expr[i]-48; } for(i=i+1;expr[i]!=')';i++)//后一个数 { t2++; sum2=sum2*10+expr[i]-48; } i++; exp[++k].value=operC(sum1,sum2); break; case'^':sum1=0;sum2=0;t1=0;t2=0;temp=1;//求次方 for(j=i-1;expr[j]>='0'&&expr[j]<='9';j--)//基数 { t1++; sum1=sum1+(expr[j]-48)*temp; temp=temp*10; } for(i=i+1;expr[i]>='0'&&expr[i]<='9';i++)//幂 { t2++; sum2=sum2*10+expr[i]-48; } k--; exp[++k].value=operX(sum1,sum2); break; case'!':sum1=0;t1=0;temp=1;//阶乘 for(j=i-1;expr[j]>'0'&&expr[j]<'9';j--) { t1++; sum1=sum1+(expr[j]-48)*temp; temp=temp*10; } i++; k--; exp[++k].value=operN(sum1); break; case'(':stack[++top]=expr[i++];//当前是左括号便进栈 break; case')':while(stack[top]!='('&&top!=1)//当前是右括号则把栈内所有运算符出栈 exp[k].charc[++t]=stack[top--]; top--;//左括号也出栈 i++; break; case'*': case'/':while(stack[top]=='*'||stack[top]=='/')//当前是*或/,如果栈顶是*或/则把栈顶出栈 exp[k].charc[++t]=stack[top--]; stack[++top]=expr[i++]; break; case'+': case'-':while(stack[top]!='('&&top!=1)//当前是+或-则把比它优先级高的运算符(既*或/)出栈 exp[k].charc[++t]=stack[top--]; stack[++top]=expr[i++]; break; default:sum=0.0;su=0.0;tem=0.1;//当前是数字则直接进栈 while(expr[i]>='0'&&expr[i]<='9') { sum=sum*10+expr[i]-48;//整数部分 i++; } if(expr[i]=='.')//小数部分 { i++; while(expr[i]>='0'&&expr[i]<='9') { su=su+(expr[i]-48)*tem; tem=tem*(0.1); i++; } } exp[++k].value=sum; exp[k].charc[++t]='#';//后缀表达式中数字后面没有运算符的话便把#放到exp[].charc[1]中 t=0; break; } } while(top!=1)//把栈内剩下的运算符出栈 exp[k].charc[++t]=stack[top--]; exp[k].charc[++t]='#'; printf("转换成后缀表达式并放入表后的分布:\n"); for(i=1;i<=k;i++) printf("%10f",exp[i].value); printf("\n"); for(i=1;i<=k;i++) for(j=1;exp[i].charc[j]!='#'&&j<5;j++) if(exp[i].charc[j]=='+'||exp[i].charc[j]=='-'||exp[i].charc[j]=='*'||exp[i].charc[j]=='/') printf("%3c",exp[i].charc[j]); printf("%c%c",exp[1].charc[1],exp[2].charc[1]);//输出后缀表达式中数值和运算符 printf("\n"); calculation(exp,k);//调用子函数进行计算求值 }
务必请哪为好心的版主花点时间看一下,给我指出错误在哪???(程序可运行,主函数很简单,就是调用子函数turn())
衷心感谢!!!