编程实现计算器。复习堆栈和队列的概念。用C语言编程实现一个简单的计算器,算术表达式中包括加、减、乘、除运算符和圆括号,并要求运算数是实型数。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#define MAXSIZE 100
#define END '\n'//END是结束符

char ops[MAXSIZE];   //运算符栈
int  ops_top;        //运算符栈顶标识
double ovs[MAXSIZE];  //操作数栈
int  ovs_top;         //操作数栈顶标识
void push_ops(char x); //运算符进栈
void push_ovs(double x); //操作数进栈
char pop_ops(); //运算符出栈
double pop_ovs();//操作数出栈
char gettop_ops();  //取出运算符栈顶元素
double gettop_ovs();  //取出操作数栈顶元素
void inistack_ops();  //初始化运算符栈
void inistack_ovs(); //初始化操作数栈
char Precede(char t1, char t2);  //判断t1与t2的优先级别
int char_In(char c); //判断c是否为运算符
double Operate(double a, char theta, double b); //对出栈的两个数计算
double  EvaluateExpression();//使用算符优先算法进行算术表示式求值
//ops[]为运算符栈,ovs[]为操作数栈
char input_q = '\n';//定义全局变量,用于缓存输入
char input_p = '\n';//定义全局变量,用于缓存输入
int temp2 = 0;//定义全局变量,用于判断是否在完全入栈前进行运算  
int main(int argc, char* argv[]) {
    printf("请输入需要运算的算数表达式:\n");
    printf("%f\n", EvaluateExpression());
    int getchar();
}

void push_ops(char x) { //运算符进栈
    if (ops_top == MAXSIZE - 1) {
        printf("运算符栈已满!上溢\n");
        exit(1);
    }
    else

    {
        ops_top++;
        ops[ops_top] = x;
    }

}

void push_ovs(double x) { //操作数进栈
    if (ovs_top == MAXSIZE - 1) {
        printf("操作数栈已满!上溢\n");
        exit(1);
    }
    else {
        ovs_top++;
        ovs[ovs_top] = x;
    }
}

char pop_ops() { //运算符出栈
    char y;
    if (ops_top == -1) {
        printf("输入有误\n");
        exit(1);
    }
    else {
        y = ops[ops_top];
        ops_top--;
    }
    return y;
}
double pop_ovs() { //操作数出栈
    double y;
    if (ovs_top == -1) {
        printf("输入有误\n");
        exit(1);
    }
    else {
        y = ovs[ovs_top];
        ovs_top--;
    }
    return y;
}
char gettop_ops() { //取出运算符栈顶元素
    if (ops_top != -1)
        return ops[ops_top];
    else {
        printf("输入有误\n");
        exit(1);
    }
}

double gettop_ovs() { //取出操作数栈顶元素
    if (ovs_top != -1)
        return ovs[ovs_top];
    else {
        printf("输入有误\n");
        exit(1);
    }
}
//置空栈
void inistack_ops() { //初始化运算符栈
    ops_top = -1;
}

void inistack_ovs() { //初始化操作数栈
    ovs_top = -1;
}

char Precede(char t1, char t2) { //判断t1与t2的优先级别
    char p;
    switch (t2) {
    case '+':
    case '-':
        if (t1 == '(' || t1 == END)//||代表或,只要有一个为真值输出为真值
            p = '<';
        else
            p = '>';
        break;
    case '*':
    case '/':
        if (t1 == '*' || t1 == '/' || t1 == ')')
            p = '>';
        else p = '<';
        break;
    case '(':
        if (t1 == ')') {
            printf("输入有误\n");
            exit(1);
        }
        else
            p = '<';
        break;
    case ')':
        switch (t1) {
        case '(':
            p = '=';
            break;
        case END:
            printf("输入有误\n");
            exit(1);
        default:
            p = '>';
        }
        break;
    case END:
        switch (t1) {
        case END:
            p = '=';
            break;
        case '(':
            printf("输入有误\n");
            exit(1);
        default:
            p = '>';
        }
    }
    return p;
}

int char_In(char c) { //判断c是否为运算符
    switch (c) {
    case '+':
        if ((!temp2) && (char_In(input_q) || input_q== '\n')) 
        {//用于检测上一个输入是否为操作符
            //temp2用于判断是否在完全入栈前进行运算
            push_ovs(0);//向操作数栈填入一个0参与负数运算
        }
        return 1;
    case '-':
        if ((!temp2) && (char_In(input_q) || input_q == '\n')) 
        {//用于检测上一个输入是否为操作符
            push_ovs(0);//向操作数栈填入一个0参与负数运算
        }
        return 1;
    case '(':
        if ((!temp2)) {
            if (input_q == ')' || (input_q >= '0' && input_q <= '9') || input_q== '.') {
                printf("输入有误\n");
                exit(0);
            }
        }
        return 1;
    case ')':
        if ((!temp2)) {
            if (!((input_q >= '0' && input_q <= '9') || input_q== ')')) {
                printf("输入有误\n");
                exit(0);
            }
        }
        return 1;
    case '*':
    case '/':
    case END:
        return 1;
    default:
        return 0;
    }
}

double Operate(double a, char theta, double b) { //对出栈的两个数计算
    double c;
    switch (theta) { //theta为运算符
    case '+':
        c = a + b; //输出0-9的ASCII码
        break;
    case '-':
        c = a - b;
        break;
    case '*':
        c = a * b;
        break;
    case '/':
        c = a / b;
    }
    return c;
}
double EvaluateExpression() {//使用算符优先算法进行算术表示式求值
    //ops[]为运算符栈,ovs[]为操作数栈
    int cache_Len = 0, i, j, f = 0;//f用于计算连续输入数字个数 
    double a, b, curnum;//curcum存储字符串转换成的小数 
    char stack_x, theta, input_c, arr[MAXSIZE];
    //arr存储数字字符串,stack_x,input_c是操作数,theta为运算符
    inistack_ops();  //初始化运算符栈
    push_ops(END);   //使结束符进栈
    inistack_ovs(); //初始化操作数栈
    input_c = getchar();
    stack_x = gettop_ops();
    while (input_c != END || stack_x != END) { //判断计算是否结束
        if (char_In(input_c)) { //若输入的字符是7种运算符之一
            input_q= input_c;//缓存上一个输入
            for (i = 0; i < f; i++) {//缓存字符串置空 
                arr[i] = '\0';
            }
            if (f) {//将数字推向操作数栈 
                push_ovs(curnum);
            }
            f = 0;//标志回滚
            switch (Precede(stack_x, input_c)) {
            case '<':
                temp2 = 0;//用于判断是否在完全入栈前进行运算 
                push_ops(input_c); //若栈顶(x)优先级<输入则输入进栈
                input_c = getchar();
                break;
            case '=':
                temp2 = 0;
                stack_x = pop_ops();//相等则出栈,脱括号接受下一个字符
                input_c = getchar();
                break;

            case '>':
                temp2++;
                theta = pop_ops();
                b = pop_ovs();
                a = pop_ovs();
                push_ovs(Operate(a, theta, b));
                break;
            }

        }
        else if ((input_c >= '0' && input_c <= '9') || input_c == '.') { //input_c是操作数
            if (input_q == ')') {//输入检查)右边不能为数字 
                printf("输入有误\n");
                exit(0);
            }
            input_q= input_c;//缓存上一个输入
//            input_c=input_c-'0';
            f++;//标志计数增加 
            arr[f - 1] = input_c;//输入的字符暂时存储到arr缓存字符串中 
            curnum = (double)atof(arr);//将字符串转换为小数
            input_c = getchar();
        }
        else {
            printf("输入有误\n");
            exit(1);
        }
        stack_x = gettop_ops();
    }
    return(gettop_ovs());
}

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值