#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define MAX 100
typedef struct charnode                      //定义一个结构体类型 
{
    char charstack;                       //定义一个存放运算符的栈 
    struct charnode *next;                  //定义一个指向栈顶的指针变量 
}StackChar; 
typedef struct datanode 
{
	int data;                        //定义一个存放数据的栈  
	struct datanode *next;               //定义一个指向栈顶的指针变量 
}StackData; 
StackChar *operation;              //定义两个变量, 分别存储数字和运算符 
StackData *data;
char Operations[7]={'+','-','*','/','(',')','#'};   //括号和运算符 
StackChar *charInitstack();                        //运算符栈的初始化栈 
StackData *dataInitstack();                        //数据栈的初始化栈 
void  charPush(StackChar *top,char x );                      //运算符进栈 
void  dataPush(StackData *top,int x );                      //运算符进栈 
void  charPop(StackChar *top);                                //运算符出栈 
void  dataPop(StackData *top);                                //数据出栈 
char  charGetpop(StackChar *top);                   //取运算符栈顶
int  dataGetpop(StackData *top);                   //取数据栈顶  
char  Precede(char a, char b);         //运算符优先级判断
int judgechar(char test);          //判断字符类型  
int Operation(int a,char operationchar,int b);       //运算
int EvaluateExpression(char inputs[]);         
 
int main()
{

    int result;
	char inputs[MAX];
    printf("请输入算式表达式");
    gets(inputs);
    result=EvaluateExpression(inputs);      //调用表达式求值函数 
    printf("结果为%d\n",result);    
return 0;
}
StackChar *charInitstack()                        //运算符栈的初始化栈 
{
	StackChar *strack;
    strack=(StackChar *)malloc(sizeof(StackChar));
	strack->next=NULL;                       
    return (strack); 
}
StackData *dataInitstack()                        //数据栈的初始化栈 
{
	StackData *strack;
    strack=(StackData *)malloc(sizeof(StackData));
	strack->next=NULL;                        
    return (strack); 
}

void  charPush(StackChar *top,char x )                      //运算符进栈 
{
	StackChar *p;
	p=(StackChar *)malloc(sizeof(StackChar));
	p->charstack=x;
	p->next=top->next; 
	top->next=p;
}
void  dataPush(StackData *top,int x )                      //操作数进栈 
{
	StackData *p;
	p=(StackData *)malloc(sizeof(StackData));
	p->data=x;
	p->next=top->next; 
	top->next=p;
}
void charPop(StackChar *top)                                //运算符出栈 
{
	StackChar *p;
	if(top->next==NULL)
	   printf("栈已空,无法出栈");
	p=top->next;
	top->next=p->next;
	free(p);
 } 
 void dataPop(StackData *top)                                //数据出栈 
{
	StackData *p;
	if(top->next==NULL)
	   printf("栈已空,无法出栈");
	p=top->next;
	top->next=p->next;
	free(p);
 } 
char charGetpop(StackChar *top)                   //取运算符栈顶       
{ 
    char x;
	if(top->next==NULL)
	{
		printf("栈空,不能取栈顶元素");
		 return 0; 
	}
	else
	{
     x=top->next->charstack;
	 return(x); 
    } 
 }
int  dataGetpop(StackData *top)                   //取数据栈顶       
{ 
    int x;
	if(top->next==NULL)
	{
		printf("栈空,不能取栈顶元素");
		 return 0; 
	}
	else
	{
     x=top->next->data;
	 return(x); 
    } 
 }
/*比较两个运算符的优先级 
 *a,b中存放待比较的运算符 
 *'>'表示a>b 
 *'0'表示不可能出现的比较 
 */  
char Precede(char a, char b)
{  
    int i,j;  
    char pre[][7]={           
    /*运算符之间的优先级制作成一张表格*/  
        {'>','>','<','<','<','>','>'},  
        {'>','>','<','<','<','>','>'},  
        {'>','>','>','>','<','>','>'},  
        {'>','>','>','>','<','>','>'},  
        {'<','<','<','<','<','=',' '},  
        {'>','>','>','>',' ','>','>'},  
        {'<','<','<','<','<',' ','='}};  
    switch(a){  
        case '+': i=0; break;  
        case '-': i=1; break;  
        case '*': i=2; break;  
        case '/': i=3; break;  
        case '(': i=4; break;  
        case ')': i=5; break;  
        case '#': i=6; break;  
    }  
    switch(b){  
        case '+': j=0; break;  
        case '-': j=1; break;  
        case '*': j=2; break;  
        case '/': j=3; break;  
        case '(': j=4; break;  
        case ')': j=5; break;  
        case '#': j=6; break;  
    }  
    return pre[i][j];                  //返回优先级 
} 
/*进行实际的运算 
 *a,b中分别以整数的形式存放两个待运算的操作数 
 *operationchar中存放代表操作符的字符 
 *结果以整数的形式返回 
 */  
int Operation(int a,char operationchar,int b)       //运算
{
	switch(operationchar)
	{
		case '+':return a+b;
		        break;
		case '-':return a-b;
		         break;
		case '*':return a*b;
		         break;
	    case '/':return a/b;
	             break;
	    default: return 0;
	             break;
	}
}
int judgechar(char test)          //判断字符类型 
{
	int i;
	int find=1;
	for(i=0;i<7;i++)
	{
		if(test==Operations[i])
		    find=0;
	}
	return find;
}  
int EvaluateExpression(char inputs[])
{  
    int n;          //保存数据 
	char c;            //保存获取下一个的字符 
    char x,oper;      //x保存栈顶元素  ,oper保存运算符  
    int a,b,sum=0,i=0;           //临时变量,a、b 分别保存两个数据 
    data=dataInitstack(data);                  //初始化数据栈 
	operation=charInitstack(operation);       //初始化一个运算符栈     
    charPush(operation,'#');                 //插入一个'#'符     
    x=charGetpop(operation);               
    while(inputs[i]!='#'||x!='#')  
    {  
        if(judgechar(inputs[i]))                      //如果返回的值为1,说明该字符为整数 
         {   
            sum=inputs[i]-'0';
            while(judgechar(inputs[i++]))
            {
            	sum=sum*10+(inputs[i++]-'0');

			}
            printf("%d",sum);
            dataPush(data,sum);               //数据进栈 
			while(inputs[i++]==' ');        //跳过一个或多个空格 
		 }
		else                            //获取的字符是运算符
        {  
            x=charGetpop(operation);              //获取运算符栈的栈顶元素  
            switch(Precede(x, inputs[i]))             //比较两个运算符的优先级 
            {  
                case '<':            //栈顶元素优先级低                      
                    charPush(operation,inputs[i]);       //运算符进栈 
                    while(inputs[i]==' ');     //获取下一个字符 
                          i++;
                    break;  
                case '=':                  //脱括号并接受下一字符   
                    charPop(operation);         //出栈 
                    while(inputs[i]==' ');     //获取下一个字符
					    i++; 
                    break;  
                case '>':                 // 退栈并将运算结果入栈   
				        oper=charGetpop(operation);                                      
                        charPop(operation);    //运算符出栈 
                        a=dataGetpop(data);
                        dataPop(data);    //数据出栈
						b=dataGetpop(data); 
                        dataPop(data);         //数据出栈 
                        dataPush(data, Operation(a, oper, b));    //将两个数据运算后再进栈  
                        while(inputs[i++]==' ');     //获取下一个字符 
                        i++;
                        break;  
            }  
        }  
        x=charGetpop(operation);                    //获取运算符栈的栈顶元素 
    }  
    n=dataGetpop(data);             //获取数据栈的栈顶元素 
    printf("%d",n);
    return n;  
}