计算器表达式求值源码

学习完C语言,数据结构,为了加深对知识的理解,就写了一个这样的一个小程序。

本程序是控制台程序,开发环境为Linux,但把代码Copy下来到Windows也可以运行。

先说一下本程序的设计思路,首先是用两个栈来存放数据和符号(数据栈和符号栈)。

算法(重点):

数字:数字无条件入栈
符号:
判断符号栈是否为空,如果为空,则无条件入栈
如果不为空,

当前符号如果为右括号:
一直去弹符号栈,直到弹出第一个左括号。

当前符号如果不为右括号:
判读栈顶元素是不是左括号
栈顶不是左括号
当前符号优先级 <= 栈顶元素的优先级,则计算。(出栈一个符号,出两个数字,先出栈的数字是右操作数,后出栈的数字是左操作数)
当前符号优先级 > 栈顶元素的优先级,符号入栈。

栈顶是左括号
当前符号无条件入栈

循环结束:
判断符号栈是否为空,如果为空,则数据栈的栈顶元素,就是最后的结果。
如果不空,一直计算,直到符号栈为空。

下面直接上代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//数据_结构体
struct stack_data{
    double arr[100];
    int top;
};
//操作符_结构体
struct stack_op{
    char str[100];
    int top;
};
//创建数据栈
struct stack_data* create_data();
//创建符号栈
struct stack_op* create_op();
//入栈
void push_data(struct stack_data* s_d,double data);
//入栈
void push_op(struct stack_op* s_o,char c);
//出栈
double pop_data(struct stack_data* s_d);
//出栈
char pop_op(struct stack_op* s_o);
//判断是否为满
int is_full_data(struct stack_data* s_d);
//判断是否为满
int is_full_op(struct stack_op* s_o);
//判断是否为空
int is_empty_data(struct stack_data* s_d);
//判断是否为空
int is_empty_op(struct stack_op* s_o);
//销毁
void destroy_data(struct stack_data* s_d);
//销毁
void destroy_op(struct stack_op* s_o);
//计算
double compute(char c,double a,double b);
//判断优先级
int judge(char c);
main(int argc,char **argv){
    struct stack_data* sd=create_data();
    struct stack_op*  so=create_op();
    char str[200];
    char *p;
    gets(str);
    for(p=str;*p;p++){
        if(*p>='0'&&*p<='9'){
            push_data(sd,atof(p));
            while(*p>='0'&&*p<='9'){
                p++;
            }
            if(*p=='.'){
                p=p+1;
                while(*p>='0'&&*p<='9')p++;
            }
            p--;
        }else{
            if(is_empty_op(so)||*p=='('){
                push_op(so,*p);
                continue;
            }else{
                if(*p==')'){
                    while(so->str[so->top-1]!='('){
                            char b1=pop_op(so);
                            double a1=pop_data(sd);
                            double a2=pop_data(sd);
                            push_data(sd,compute(b1,a1,a2));
                    }
                    pop_op(so);
                }else{
                    if(so->str[so->top-1]!='('){
                        if(judge(*p)<=judge(so->str[so->top-1])){
                            char b2=pop_op(so);
                            double a3=pop_data(sd);
                            double a4=pop_data(sd);
                            push_data(sd,compute(b2,a3,a4));
                            p--;
                            continue;
                        }else{
                            push_op(so,*p);
                        }
                    }else{
                        push_op(so,*p);
                    }
                }
            }
        }    
    }
    while(is_empty_op(so)==0){
        char b3=pop_op(so);
        double a5=pop_data(sd);
        double a6=pop_data(sd);
        push_data(sd,compute(b3,a5,a6));
    }
    while(is_empty_data(sd)==0){
        printf("%f ",pop_data(sd));
    }
    destroy_data(sd);
    sd=NULL;
    destroy_op(so);
    so=NULL;
    return 0;
}
//创建数据栈
struct stack_data* create_data(){
    struct stack_data* s=malloc(sizeof(*s));
    memset(s,0,sizeof(*s));
    s->top=0;
}
//创建符号栈
struct stack_op* create_op(){
    struct stack_op* s=malloc(sizeof(*s));
    memset(s,0,sizeof(*s));
    s->top=0;
}
//入栈
void push_data(struct stack_data* s_d,double data){
     s_d->arr[s_d->top]=data;
    s_d->top+=1;
}
//入栈
void push_op(struct stack_op* s_o,char c){
    s_o->str[s_o->top]=c;
    s_o->top+=1;
}
//出栈
double pop_data(struct stack_data* s_d){
    s_d->top-=1;
    double data=s_d->arr[s_d->top];
    return data;
}
//出栈
char pop_op(struct stack_op* s_o){
    s_o->top-=1;
    char c=s_o->str[s_o->top];
    return c;
}
//判断是否为满
int is_full_data(struct stack_data* s_d){
    if(s_d->top==100)
        return 1;
    return 0;
}
//判断是否为满
int is_full_op(struct stack_op* s_o){
    if(s_o->top==100)
        return 1;
    return 0;
}
//判断是否为空
int is_empty_data(struct stack_data* s_d){
    if(s_d->top==0)
        return 1;
    return 0;
}
//判断是否为空
int is_empty_op(struct stack_op* s_o){
    if(s_o->top==0)
        return 1;
    return 0;
}
//销毁
void destroy_data(struct stack_data* s_d){
    free(s_d);
    s_d=NULL;
}
//销毁
void destroy_op(struct stack_op* s_o){
    free(s_o);
    s_o=NULL;
}
//计算
double compute(char c,double a,double b){
    if(c=='+')return b+a;
    if(c=='-')return b-a;
    if(c=='*')return b*a;
    if(c=='/')return b/a;
}
//判断优先级
int judge(char c){
    if(c=='+'||c=='-')
        return -1;
    if(c=='*'||c=='/')
        return 0;
}

这是初级版本,只能算加减乘除和带括号的表达式,支持小数,以后会更新。

希望和大家多交流,分享。

原文地址:https://www.cnblogs.com/wzqstudy/p/9474890.html