#include#define new1 (no*)malloc(sizeof(no))
#define deletenode p2->prec=p1->prec;free(p1);p1=p2->prec;p1->next=p2
#define error1 p1=head;p2=head-> next;if(p2){while(p2!=r){free(p1);p1=p2;p2=p2->next;}free(p1);p2->ope=1;return p2;}else{p1->ope=1;return p1;}
#define fun(a,b,c) if(!numbegin)if(getchar()==a)if(getchar()==b)if(getchar()==(){p=operate();if(p->ope){r->next=p;r=p;error1;}num2=c(p->num);free(p);numbegin=1;numend=1;}else{error1;}else{error1;}else{error1;}
#define datadeal p=new1;p->num=(num1+num2)*minus;isfloat=0;num1=0;num2=0;minus=1;numbegin=0;flength=1;numend=0;r->next=p;p->prec=r;r=p;p->ope=c
typedef struct numope{
double num;
char ope;
struct numope *prec,*next;
}no;
no *calculate(no *head,no *rear){
no *p1,*p2;
p2=rear;
p1=rear->prec;
while(p1!=head)
if(p1->ope==^){
p2->num=pow(p1->num,p2->num);
deletenode;
}else{
p2=p1;
p1=p1->prec;
}
while(p1!=rear){
p2=p1->next;
if(p1->ope==*){
p2->num=p1->num*p2->num;
deletenode;
}
if(p1->ope==/){
p2->num=p1->num/p2->num;
deletenode;
}
p1=p2;
}
p1=head;p2=head->next;
while(p1!=rear){
p2=p1->next;
if(p1->ope==+){
p2->num=p1->num+p2->num;
deletenode;
}
if(p1->ope==-){
p2->num=p1->num-p2->num;
deletenode;
}
p1=p2;
}
free(head);
return rear;
}
no *operate(){
char c,flength,numbegin,numend,isfloat;
double num2;
int num1,minus;
no *head,*p,*r,*p1,*p2;
num1=0;num2=0;minus=1;numbegin=0;numend=0;isfloat=0;flength=1;r=head=new1;head->ope=0;head->next=0;
c=getchar();
while(c!=)&&c!=#){
if(c>=48&&c<=57){
if(numend){error1;}
numbegin=1;
if(isfloat) num2+=(c-48)*pow(0.1,flength++);
else num1=num1*10+c-48;
c=getchar();
continue;
}
switch(c){
case .:isfloat=1;break;
case -:if(numbegin){datadeal;}else minus=-1;break;
case *:
case /:
case ^:
case +:if(numbegin){datadeal;}break;
case (:if(numbegin){error1;}
else{
p=operate();
if(p->ope){r->next=p;r=p;error1;}
num2=p->num;free(p);numbegin=1;numend=1;
}
break;
case s:fun(i,n,sin) break;
case c:fun(o,s,cos) break;
case t:fun(a,n,tan) break;
case a:fun(b,s,abs) break;
case e:fun(x,p,exp) break;
case l:fun(o,g,log) break;
case f:fun(l,o,floor) break;
case p:if(numbegin){error1;}else if(getchar()==i){num2=3.141592653589793062;numbegin=1;numend=1;}else{error1;}
}
c=getchar();
}
datadeal;
r->ope=0;
p=calculate(head,r);
return p;
}
main(){
no *head,*p,*r;
char c;
while(1){
printf("==================================instruction===================================");
printf("Input floats and + - * / ^ ( ) to claculate.\n");
printf("These are functions you can use with a bracket.\n");
printf("Input\tsin\tcos\ttan\tabs\texp\tlog\tflo\t\n");
printf("To\tsin\tcos\ttan\tabs\texp\tln\tfloor\t\n");
printf("Input pi to 3.14...\n");
printf("Make sure your expression is end with a #\n");
printf("===================================expression===================================");
head=operate();
if(head->ope)printf("error expression\n");
else printf("%.12lf\n",head->num);
printf("Press C or c to continue,else to quit\n");
c=getchar();while(c!=10){c=getchar();}c=getchar();
if(c==C||c==c)system("CLS");
else exit(1);
}
}
6. 运行结果:
7. 调试分析:
调试时由于指数运算^是右结合而采用了双向链表,此外,注意到了初始化的重要性。不足:考虑到表达式并不太复杂且编译的复杂性所以函数名的第一个字母不能相同且只能是三个字母的,这使得天花板函数ceil()并没有被加进去。
8. 编者的话:
对栈的操作的题目也被编译了,这里只呈现表达式求值。