用C语言实现的计算器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define  ERROR -1
#define   OK   1
#define STACK_INIT_SIZE  100
#define STACKINCREMENT 20
int error=0;
char expr[255];
char *ptr=expr;
typedef struct
{
    int stacksize;
    char *base;
    char *top;
} Stack;
typedef struct
{
    double stacksize;
    double *base;
    double *top;
} Stack2;
Stack OPTR;
Stack2 OPND;
int InitStack(Stack *s) //初始化字符顺序栈
{
    s->base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
    if(!s->base)   return ERROR;
    s->top=s->base;
    s->stacksize=STACK_INIT_SIZE;
    return OK;
}
int InitStack2(Stack2 *s)//初始化数字顺序栈
{
    s->base=(double*)malloc(STACK_INIT_SIZE*sizeof(double));
    if(!s->base)   return ERROR;
    s->stacksize=STACK_INIT_SIZE;
    s->top=s->base;
    return OK;
}
int In(char ch)//是运算符则返回1//
{
    return(ch!='0'&&ch!='1'&&ch!='2'&&ch!='3'&&ch!='4'&&ch!='5'&&ch!='6'&&ch!='7'&&ch!='8'&&ch!='9'&&ch!='.');
}
int Push(Stack *s,char ch)//进栈
{
    *s->top=ch;
    s->top++;
    return 0;
}
int Push2(Stack2 *s,double ch)
{
    *s->top=ch;
    s->top++;
    return 0;
}
char Pop(Stack *s)//出栈
{
    char p;
    s->top--;
    p=*s->top;
    return p;
}
double Pop2(Stack2 *s)
{
    double p;
    s->top--;
    p=*s->top;
    return p;
}
char GetTop(Stack s)//读栈顶元素
{
    char p=*(s.top-1);
    return p;
}
double GetTop2(Stack2 s)
{
    double p=*(s.top-1);
    return p;
}
char Precede(char c1,char c2)//优先级表//
{
    int i=0,j=0;
    static char array[49]=
    {
        '>','>','<','<','<','>','>',
        '>','>','<','<','<','>','>',
        '>','>','>','>','<','>','>',
        '>','>','>','>','<','>','>',
        '<','<','<','<','1','=','>',
        '>','>','>','>', '2','>','>',
        '<','<','<','<','<','3','='
    };
    switch(c1)
    {
    case '+':
        i=0;
        break;
    case '-':
        i=1;
        break;
    case '*':
        i=2;
        break;
    case '/':
        i=3;
        break;
    case '(':
        i=4;
        break;
    case ')':
        i=5;
        break;
    case '=':
        i=6;
        break;
    default:
        printf("表达式含有非法运算符!!!\n");
        error++;
        break;
    }
    switch(c2)
    {
    case'+':
        j=0;
        break;
    case'-':
        j=1;
        break;
    case'*':
        j=2;
        break;
    case'/':
        j=3;
        break;
    case'(':
        j=4;
        break;
    case')':
        j=5;
        break;
    case'=':
        j=6;
        break;
    default:
        printf("表达式含有非法运算符!!!\n");
        error++;
        break;
    }
    return (array[7*i+j]);
}
double Operate(double a,char op,double b)//计算操作函数//
{
    switch(op)
    {
    case'+':
        return (a+b);
    case'-':
        return (a-b);
    case'*':
        return (a*b);
    case'/':
    {
        if(b==0)
        {
            printf("表达式零不能做除数!!\n");
            error++;
            return 0;
        }
        else return (a/b);
    }
    }
    return 0;
}
double EvalExpr()//表达式处理算法
{
    InitStack(&OPTR);
    Push(&OPTR,'=');
    InitStack2(&OPND);
    char c,theta,x;
    int n=0;
    double m;
    double a,b;
    c=*ptr++;
    while(c!='='||GetTop(OPTR)!='=')
    {
        if(!In(c))//如果c不是运算符
        {
            if(!In(*(ptr-1)))   ptr=ptr-1;//校验数字
            m=strtod(ptr,NULL);//取字符串前面数字段转化为浮点型
            Push2(&OPND,m);
            while(!In(*(ptr)))   ptr++;
            c=*ptr;
        }
        else
        {
            switch(Precede(GetTop(OPTR),c))
            {
            case'<':
                Push(&OPTR,c);
                ptr++;
                c=*ptr;
                break;
            case'=':
                x=Pop(&OPTR);
                ptr++;
                c=*ptr;
                break;
            case'>':
                theta=Pop(&OPTR);
                b=Pop2(&OPND);
                a=Pop2(&OPND);
                Push2(&OPND,Operate(a,theta,b));
                break;
            case'1':
                printf("表达式多出一个左括号\n");
                error++;
                break;
            case'2':
                printf("表达式出现非法括号\n");
                error++;
                break;
            case'3':
                printf("表达式多出一个右括号\n");
                error++;
                break;
            default:
                printf("表达式出现未知错误\n");
                error++;
                break;
            }
            if(error!=0)    break;
        }
    }
    return GetTop2(OPND);
}
void printInfo()//输出界面函数//
{
 printf("\n***************************************************************\n");
 printf("*   10031010=== 夏某    1003101=== 王某       *");
 printf("\n***************************************************************\n");
 printf("*******                                                 *******");
    printf("\n*******    程序功能为:用顺序栈实现算术表达式的求值     ******* \n");
 printf("*******                                                 *******");
    printf("\n*******      \thelp\t显示使用说明                    ******* \n");
 printf("*******                                                 *******");
    printf("\n*******      \tcls\t清除屏幕                        ******* \n");
 printf("*******                                                 *******");
    printf("\n*******      \texit\t退出程序                        ******* \n");
 printf("*******                                                 *******");
    printf("\n*******    请输入这样的计算表达式3.2*(1.9+2.8)=         ******* \n");
 printf("*******                                                 *******");
 printf("\n***************************************************************\n");
    printf("-> ");
}

int main()
{
    double z=0;
    char EXIT[] = "exit";
    char CLEAR[] = "cls";
    char HELP[] = "help";
    //int expression_length,str_length;
    printInfo();
    while(gets(expr))
    {
        ptr=expr;
        error=0;
        if(!strcmp(EXIT,expr))
        {
            exit(0);
        }
        else if(!strcmp(CLEAR,expr))
        {
            system("CLS");
            printf("-> ");
            continue;
        }
        else if(!strcmp(HELP,expr))
        {
            printInfo();
            continue;
        }
        else if(!strcmp("",expr))
        {
            printf("输入数据不能为空\n");
            printf("-> ");
            continue;
        }
        else{
            z=EvalExpr();
           // printf("   %s",expr);
            if(error==0)
                printf("结果为:%lf\n\n",z);
            else
                printf("出现错误\n");
        }
        printf("-> ");
    }
    return 0;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值