📄 calculator.c
字号:
#define OVERFLOW -2
#define ERROR 0
#define SIZE 35
#define ASIZE 70
#define INC 10
#include <stdio.h>/*包含flushall函数*/
#include <malloc.h>
#include <stdlib.h>/*包含exit函数*/
#include <conio.h>/*包含getch函数*/
typedef struct {float *base,*top;int size;}ndstack;
typedef struct {char *base,*top;int size;}trstack;
void initndstack(ndstack *opnd)
{
opnd->base=(float *)malloc(SIZE*sizeof(float));
if(!opnd->base){printf("overflow\n");exit(OVERFLOW);}
opnd->top=opnd->base;opnd->size=SIZE;
}
void inittrstack(trstack *optr)
{
optr->base=(char *)malloc(SIZE*sizeof(char));
if(!optr->base){printf("overflow\n");exit(OVERFLOW);}
optr->top=optr->base;optr->size=SIZE;
}
float ndgettop(ndstack *opnd)
{
if(opnd->top==opnd->base){printf("the expression is incorrect,exit in ndgettop\n");exit(ERROR);}
return *(opnd->top-1);
}
char trgettop(trstack *optr)
{
if(optr->top==optr->base){printf("the expression is incorrect,exit in trgettop\n");exit(ERROR);}
return *(optr->top-1);
}
void trpush(trstack *optr,char e)
{
if(optr->top-optr->base>=optr->size)
{
optr->base=(char *)realloc(optr->base,(optr->size+INC)*sizeof(char));
if(!optr->base){printf("overflow\n");exit(OVERFLOW);}
optr->top=optr->base+optr->size;
optr->size+=INC;
}
*(optr->top++)=e;
}
void ndpush(ndstack *opnd,float e)
{
if(opnd->top-opnd->base>=opnd->size)
{
opnd->base=(float *)realloc(opnd->base,(opnd->size+INC)*sizeof(float));
if(!opnd->base){printf("overflow\n");exit(OVERFLOW);}
opnd->top=opnd->base+opnd->size;
opnd->size+=INC;
}
*(opnd->top++)=e;
}
float ndpop(ndstack *opnd)
{
if(opnd->top==opnd->base)
{printf("the expression is incorrect,exit in ndpop\n");exit(ERROR);}
return *(--opnd->top);
}
char trpop(trstack *optr)
{
if(optr->top==optr->base)
{printf("the expression is incorrect,exit in trpop\n");exit(ERROR);}
return *(--optr->top);
}
int code(char ch)
{
switch(ch)
{
case '+':return 0;case'-':return 1;case'*':return 2;
case'/':return 3;case'(':return 4;case')':return 5;
case'=':return 6;default:printf("wrong character\n");exit(ERROR);
}
}
int precede(char c1,char c2)
{
int i,j,a[7][7]={0};
a[0][2]=a[0][3]=a[0][4]=a[1][2]=a[1][3]=a[1][4]=a[2][4]=a[3][4]=1;
for(i=0;i<=4;i++)a[4][i]=a[6][i]=1;
a[4][5]=a[6][6]=2;a[4][6]=a[5][4]=a[6][5]=3;
i=code(c1);j=code(c2);return a[i][j];
}
float operate(float a,char theta,float b)
{
switch(theta)
{
case'+':return a+b;case'-':return a-b;
case'*':return a*b;case'/':return a/b;
}
}
float EvaluateExpression(trstack *optr,ndstack *opnd,char d[])
{
int f=0,i=0,flag=0;float s=0,p=1,a,b;char theta,c=d[i];i++;
while(1)
{
if(c>=48&&c<=57)
{
if(!flag){s=s*10+(c-48);f=1;c=d[i];i++;}
else
{
if(flag<=6){p*=10;s+=(c-48)/p;}
c=d[i];i++;flag++;f=1;
}
}
else if(c==46){flag++;c=d[i];i++;}
else
{
/*printf("s=%f,f=%f\n",s,f);*/
if(f){ndpush(opnd,s);s=0;p=1;flag=f=0;}
if(c=='='&&trgettop(optr)=='=')break;
switch(precede(trgettop(optr),c))
{
case 0:theta=trpop(optr);b=ndpop(opnd);a=ndpop(opnd);
ndpush(opnd,operate(a,theta,b));/*printf("top=%f\n",ndgettop(opnd));*/break;
case 1:trpush(optr,c);c=d[i];i++;break;
case 2:trpop(optr);c=d[i];i++;break;
case 3:printf("the expression is incorrect,exit for not match\n");exit(ERROR);
}
}
}
if(opnd->base+1!=opnd->top){printf("the expression is incorrect,exit5\n");exit(ERROR);}
return ndgettop(opnd);
}
int main()
{
ndstack opnd;trstack optr;char a[ASIZE];int n;
printf("input expression(less than %d alphabets)\n",ASIZE);
while(1){/*若想让改程序真正实现可控制循环,需要在每次循环时将栈清空且输入出错时不能用exit*/
/*要想实现修改,需要用bioskey函数和字符窗口*/
for(n=0;n<ASIZE;n++)
{
a[n]=getch();putchar(a[n]);if(a[n]=='=')break;else if(a[n]==27)exit(0);
}
if(n>ASIZE){printf("overlength\n");exit(ERROR);}
initndstack(&opnd);inittrstack(&optr);trpush(&optr,'=');
printf("%f\n",EvaluateExpression(&optr,&opnd,a));
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -