文章标题

main.c

    #include <stdlib.h> //为了使用atof函数 
    #include <stdio.h>
    #include <math.h>
    #include "op.h"
    #include "stack.h"
    #define MAXOP 100  //操作数或运算符的最大长度
    #define NUMBER '0' // 标识找到一个数

    // S-sin E-exp P-pow  

    int getop(char []);
    void push(double);
    double pop(void); 
    //逆波兰计算器 
    int main(void)
    {
        int type;
        double op2,op1,copy,temp,var,print;
        char s[MAXOP];
        int state=0;
        int state_1=0;
        char ch;

        while((type=getop(s))!=EOF){    

            switch(type){
                case NUMBER:
                     push(atof(s));
                     break;
                case '+':
                    push(pop()+pop());
                    break;
                case '*':
                    push(pop()*pop());
                    break;
                case '-':
                    op2=pop();
                    push(pop()-op2);
                    break;
                case '/':
                    op2=pop();
                    if(op2!=0.0)
                       push(pop()/op2);
                    else
                        printf("error: zero divisor\n");
                    break;
                case '\n':
                    if(state==0){  //状态机 针对栈的操作再输入对应操作符之后需要输入'\n' 这里的'\n'不能打印出栈元素 
                       print=pop();
                       push(print); 
                       printf("\t%.8g\n",pop()); //回车键 打印栈顶元素 (出栈)
                       } 
                    else 
                       state=0;  //恢复原状态 
                    break;
                case 'p': //不弹出元素的情况下打印栈顶元素 
                    op2=pop(); //弹出栈顶 
                    printf("\t栈顶元素%.8g\n",op2);
                    push(op2);  //压回栈顶
                    state=1;
                    break; 
                case 'c':  //复制栈顶元素到copy 
                    op2=pop(); 
                    copy=op2;
                    push(op2);
                    printf("You have copied the top element of stack to the variable copy : copy= %.8g\n",copy);
                    state=1;
                    break; 
                case 'd': //交换栈顶两个元素的值
                    op1=pop();
                    op2=pop();
                    push(op1);
                    push(op2);
                    printf("You have change the first two element of stack,use 'p' to check it.\n");
                    state=1;
                    break; 
                case 't':// 清空栈
                    clear();
                    state=1;
                    break; 
                case 'S': //正弦
                    push(sin(pop()));
                    break; 
                case 'E': //exp
                    push(exp(pop()));
                    break; 
                case 'P': //power
                    op2=pop();
                    push(pow(pop(),op2));
                    break;
                case 'v':     //变量按钮     变量模块 (本来想函数化的,牵扯到状态机没成功) 
                    if(state_1==0){
                        state_1=1;
                        printf("请为变量var赋值:\n");
                        scanf("%lf",&var); //scanf函数读入double类型 %lf 否则会出错 
                        state=1;
                        break;
                    }
                        if(state_1==1){
                           if((ch=getchar())=='a'&&(ch=getchar())=='r'){
                           //state=1;
                           push(var);   
                           break; 

                        } 
                        else
                            printf("\terror\n");
                        state_1=0; 
                        break; 
                    }   
                case 's':  // 查看最近打印的值             
                        printf("最近打印的值%g\n",print);
                        state=1;
                        break;
                case '%':
                        op2=pop();
                        if(((op1=pop())==(int)op1)&&(op2==(int)op2)&&(op2!=0.0)){
                          push((int)op1%(int)op2); 
                       }
                       else
                        printf("zero divisor or there is a float\n");
                       break; 
                default:
                printf("error: unknown comand %s\n",s);
                break;

            }

        }
        return 0;
    }

头文件

“op.h”

    #include<ctype.h>
    #define NUMBER '0' // 标识找到一个数
    #define MAXVAL 100 //栈val的最大深度

    int getch(void);

    void ungetch(int);

    /*getop函数:获取下一个运算符或数值操作数*/
    int getop(char s[])
    {
        int i,c,sign=1;
        while((s[0]=c=getchar())==' '||c=='\t')
              ;
        s[1]='\0';
        if(!isdigit(c)&&c!='.'&&c!='-'){

               return c; //不是数 也不是'-' 
        }

        i=0;
        if(isdigit(c)||c=='-'){

            while(isdigit(s[++i]=c=getch()))
                  ;

            if(c == '-')  
              if(isdigit(c = getch()) || c == '.')  //表明是负号 
                s[++i] = c;  
              else  
            {  
                if(c != EOF)  
                    ungetch(c);  
                return '-';   // 表明是减号 
            }  

        } 

        if(c=='.')
                while(isdigit(s[++i]=c=getch()))
                ;
        s[i]='\0';
        if(c!=EOF)
           ungetch(c);
        return NUMBER;

    } 

    #define BUFSIZE 100
    char buf[BUFSIZE]; //用于ungetch函数的缓冲区
    int bufp = 0; //buf中下一个空闲位置

    int getch(void) //取一个字符
    {
        return (bufp>0? buf[--bufp]:getchar());
    } 

    void ungetch(int c)
    {
        if(bufp>=BUFSIZE)
            printf("Too many characters\n");
        else 
            buf[bufp++]=c;
    }

“stack.h”

    int sp=0;//下一个空栈的位置
    double val[MAXVAL]; //值栈
    //push函数:把 f 压到值栈中
    void push(double(f))
    {
        if(sp<MAXVAL)
            val[sp++]=f;
        else 
        printf("error: stack full, can't push%g\n",f);
    }  

    //pop函数: 弹出并返回栈顶的值 
    double pop(void)
    {
        if(sp>0)
           return val[--sp];
        else{
            printf("error: stack empty\n");
            return 0.0;
        }   
    } 

    void clear(void)
    {
        sp=0;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值