【c语言小项目】简单计算器

来源:互联网 发布:mac直播音效软件下载 编辑:程序博客网 时间:2024/05/21 15:50

应用栈实现表达式求值,具体思路如下:

  • 创建两个栈,一个用来存数字,一个用来存符号。起始,数字栈为空,符号栈底先存一个’\n’用来标记开始,用输入的’\n’标记结尾。

  • 开始处理输入的字符,当字符是运算符号时,根据运算符的优先关系:如果当前符号优先关系大于栈顶符号,入栈;如果小于,则拿出栈顶符号,再从数字栈拿出两个数字进行运算,将结果放在数字栈里;如果等于,说明是两个括号相遇,此时括号内的运算已经完成,将括号脱栈。

  • 遇到用户输入的回车符结束运算,并从数字栈里拿出运算结果。

代码如下:

#include<stdio.h>#include<stdlib.h>#define STACKMAX 100#define STACKADD 10/**********************************符号栈****************************/typedef struct StackChar{    char *base;    char *top;    int stacksize;}SC;void InitStackSC(SC *S){    S->base = (char*)malloc(STACKMAX*sizeof(char));    S->top = S->base;    S->stacksize = STACKMAX;}void PushSC(SC *S,char e){    if(S->top - S->base >= S->stacksize)    {        S->base = (char*)realloc(S->base,(S->stacksize+STACKADD)*sizeof(char));        if(!S->base)            return;        S->top = S->base + S->stacksize;        S->stacksize += STACKADD;    }    *S->top++ = e;}int StackEmptySC(SC* S){    if(S->base == S->top)        return 1;    return 0;}void PopSC(SC *S,char *e){    *e = *--S->top;}char GetTopSC(SC *S){    if(StackEmptySC(S))        return 0;    return *(S->top-1);}/**************************************数字栈******************/typedef struct StackData{    double *base;    double *top;    int stacksize;}SD;void InitStackSD(SD *S){    S->base = (double*)malloc(STACKMAX*sizeof(double));    S->top = S->base;    S->stacksize = STACKMAX;}int StackEmptySD(SD* S){    if(S->base == S->top)        return 1;    return 0;}void PushSD(SD *S,double e){    if(S->top - S->base >= S->stacksize)    {        S->base = (double*)realloc(S->base,(S->stacksize+STACKADD)*sizeof(double));        if(!S->base)            return;        S->top = S->base + S->stacksize;        S->stacksize += STACKADD;    }    *S->top++ = e;}void PopSD(SD *S,double *e){    *e = *--S->top;}double GetTopSD(SD *S){    if(StackEmptySD(S))        return 0;    return *(S->top-1);}/*******************************************/char Precede(char x,char y)//判断操两个操作符优先度{    int i,j;    char ch[7] = {'+','-','*','/','(',')','\n'};    char cmp[7][7] = {        //+  -    *  /   (   )    \n        {'>','>','<','<','<','>','>',},// +        {'>','>','<','<','<','>','>',},// -        {'>','>','>','>','<','>','>',},// *        {'>','>','>','>','<','>','>',},// /        {'<','<','<','<','<','=',' ',},// (        {'>','>','>','>',' ','>','>',},// )        {'<','<','<','<','<',' ','=',},// \n            };    for(i=0; i<7; i++)    {        if(ch[i] == x) break;    }    for(j=0; j<7; j++)    {        if(ch[j] == y) break;    }    return cmp[i][j];}double Operate(double a,char op,double b)//计算函数{    switch(op)    {    case'+':        return a+b;        break;    case'-':        return a-b;        break;    case'*':        return a*b;        break;    case'/':        return a/b;        break;    default:        return 0;    }}int In(char c)//检查是否为符号,是返回1,否则返回0{    if(c=='+' || c=='-' || c=='*' || c=='/' || c=='(' || c==')' || c=='\n')        return 1;    return 0;}double EvaluateExpression(){    SC C;//运算符    SD D;//操作数    SD *OPND = &D;    SC *OPTR = &C;    double a,b;    char c,oper,tmp;    InitStackSC(OPTR);//运算符    PushSC(OPTR,'\n');    InitStackSD(OPND);//操作数    c = getchar();    while(c!='\n' || GetTopSC(OPTR)!='\n')    {        if(!In(c))//不是运算符,进栈        {            c -= '0';//将字符转化为数字            PushSD(OPND,c);            c = getchar();        }        else        {            switch(Precede(GetTopSC(OPTR),c))            {            case'>'://栈顶元素优先权大,退栈并将运算结果入栈                PopSC(OPTR,&oper);                PopSD(OPND,&b);                PopSD(OPND,&a);                PushSD(OPND,Operate(a,oper,b));                break;            case'='://脱括号并且接受下一个字符                PopSC(OPTR,&tmp);                c = getchar();                break;            case'<'://入符号栈并接收下一个字符                PushSC(OPTR,c);                c = getchar();                break;            }        }    }    return GetTopSD(OPND);}int main(){    printf("%0.2lf\n",EvaluateExpression());    return 0;}

测试结果:
这里写图片描述

此程序没有检测输入,如果多出空格或者乱输会得到错误答案,添加一个函数检测c即可,留坑,日后来填。

原创粉丝点击