console calc 控制台 计算器

#pragma once
#include <stdio.h>  
#include <math.h>  
#include <ctype.h>  
#include <stdlib.h>  
#include <string.h>  
#define PI (3.14159265358979323846/180.0) //改为角度输入  
#define EPS (1e-7)        //浮点数比较  
#define N 8               //函数名称字符的最大长度   
//#define M 7               //现支持函数个数  
#define MAX_INFIX 128     //表达式的最大长度   
  
double EvExpre(void);     //表达式求值函数   
  
int calcMain( void )   
{   
    while(8)   
    {   
        printf("\n请输入计算表达式:");   
        rewind(stdin);   
        printf("表达式值为:%.13lg\r",EvExpre());   
    }   
    return 0;   
}   
static double ftoa_zw(char *c)       //字符转实数   
{   
    double  n=0.0;   
    if(isdigit(*c))   
        do  
        {   
            n=n*10.0+(*c-'0');   
        }   
        while(isdigit(*c=getchar()));   
    if(*c=='.')   
    {   
        double m=1.0;   
        while(isdigit(*c=getchar()))   
        {   
            n=n*10.0+(*c-'0');   
            m*=10.0;   
        }   
        n /= m;   
    }   
    return n;   
}   
static int isfunc(const char *cur)//是否是函数符(是返回下标,否返-1)   
{   
    const char *ap[]= {"sin","asin","cos","acos","tan","exp","log",NULL};   
    const char **i;   
    for(i=ap;*i!=NULL; ++i)   
        if(strcmp(*i,cur)==0)   
            return (int)(i-ap);   
    return -1;   
}   
static double mathfuc(double n,int i)//函数运算   
{   
    double (*f[])(double)= {sin,asin,cos,acos,tan,exp,log,NULL};//一一对应   
    if(i<0 || i>= sizeof(f)/sizeof(f[0])-1 )   
    {   
        puts("程序异常退出...");   
        exit(-1);   
    }   
    if(i<5) n *= PI;   
    return f[i](n);   
}   
static int func(double *op,int *j,char *c)//函数判定、求值或进符号栈   
{   
    char temp[N+1]= {0};   
    int i=0;   
    do  
    {   
        temp[i++]=*c;   
    }   
    while(islower(*c=getchar()) && i < N );   
    if((i=isfunc(temp))!=-1)//如果是函数符   
    {   
        if(*c=='(')         //直接入符号栈 sin(30+60)   
            return ('0'+i); //函数代码入数字栈   
              //return i;   
        int sig=1;   
        if(*c=='-' || *c=='+')   
        {   
            if(*c=='-') sig=-1;   
            *c=getchar();   
        }   
        if(isdigit(*c) || *c=='.')   
        {   
            *(op+1)=mathfuc(sig*ftoa_zw(c),i);  //计算结果入数字栈 sin30   
            *j += 1;   
            return 0;     //成功返0   
            //return -2   //成功返-2   
        }   
    }   
    if(*c=='\n') puts("语法错误..."); // sin   
    return -1;   
}   
static int isoper(const char oper)//是否运算符   
{   
    const char *p="+-*/^!F";   
    for(; *p && *p!=oper; ++p);   
    return *p ? 1 : 0;   
}   
static double fanc(double n)//阶乘函数(171以内)   
{   
    if(n<-EPS)   
    {   
        puts("对负数阶乘无效...");   
        return 0.0;   
    }   
    int i,t;   
    double num=1.0;   
    for(t=(int)n,i=1; i<=t; ++i)   
        num*=i;   
    return num;   
}   
static int precede(char top,char cur)/*判定优先级函数*/  
{   
    char ch='>';//默认栈顶优先级高   
    switch(cur)   
    {   
    case '+':   
    case '-':   
        if(top=='(' || top=='\n')   
            ch='<';   
        break;   
    case '*':   
    case '/':   
        if(top=='+' || top=='-' ||top=='(' || top=='\n')   
            ch='<';   
        break;   
    case '(':   
        ch='<';   
        break;   
    case ')':   
        if(top=='(')   
            ch='=';   
        break;   
    case '\n':   
        if(top=='\n')   
            ch='=';   
        if(top=='(') ch=-1;   
        break;   
    case '^':   
        if(top!='!'&&top!='F')   
            ch='<';   
        break;   
    case '!':   
        if(top!='^'&&top!='F')   
            ch='<';   
        break;   
    case 'F':   
        if(top!='^'&&top!='!')   
            ch='<';   
        break;   
    default:   
        ch=-1;   
        break;   
    }   
    return ch;   
}   
static int operate(double *op,int *i,char oper)//二元运算(利于阶乘)   
{   
    if(oper!='!'&&*i==0)   
    {   
        puts("语法错误...");   
        return 0;   
    }   
    *i-=1;   
    switch(oper)   
    {   
    case '+':   
        *(op-1)+=*op;   
        break;   
    case '-':   
        *(op-1)-=*op;  //注意顺序   
        break;   
    case '*':   
        *(op-1)*=*op;   
        break;   
    case '/':   
        if(*op==0)   
        {   
            fprintf(stderr,"错误:除数为零\n");   
            return 0;   
        }   
        *(op-1)/=*op;   
        break;   
    case '^':   
        *(op-1)=pow(*(op-1),*op);   
        break;   
    case '!':   
        *i+=1;   
        *op=fanc(*op);   
        break;   
    case 'F':   
        *(op-1)=mathfuc(*op,(int)(*(op-1)));   
        break;   
    }   
    return 1;   
}   
double EvExpre(void)    //中缀表达式求值函数   
{   
    char c;   
    register int sig=1;      //正负数判断   
    int i=-1;                //数字栈的栈顶指针   
    register int j=0;        //符号栈的栈顶指针   
    double OP[MAX_INFIX/2]= {0.0};    //数字栈   
    char OPER[MAX_INFIX/2]= {'\n'};   //符号栈   
    c=getchar();   
    while(c!='\n' || OPER[j]!='\n')   
    {   
        if(i==-1 && (c=='-'||c=='+'))  //负数   
        {   
            sig=(c=='-')?-1:1;   
            c=getchar();   
        }   
        if(isdigit(c)||c=='.')   
        {   
            OP[++i]=ftoa_zw(&c)*sig;   
            sig=1;   
        }   
        if(islower(c))   
        {   
            int n;   
            if((n=func(&OP[i],&i,&c))==-1)//语法错误   
                return 0.0;   
            if(n)  //if(n!=-2)   
            {   
                OPER[++j]='F';          //'F'代表是函数符   
                OP[++i]=(double)(n-'0');//函数符代码入数字栈   
                //OP[++i]=(double)n;   
            }   
        }   
        switch(precede(OPER[j],c))   
        {   
        case '<':   
            OPER[++j]=c;   
            if((c=getchar())=='-'||c=='+')   
            {   
                sig=(c=='-')?-1:1;   
                c=getchar();   
            }   
            break;   
        case '=':   
            if(j>0)   
            {   
                --j;   
                c=getchar();   
            }   
            break;   
        case '>':   
            if(isoper(OPER[j]))   
                if(!operate(&OP[i],&i,OPER[j--])) return 0.0;   
            break;   
        default:   
            puts("语法错误...");   
            return 0.0;   
        }   
    }   
    return OP[i];   
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值