在终端输入一个表达式(四则运算及括号),计算表达式的值。
calculator.h
#ifndef __CALCULATOR_H__
#define __CALCULATOR_H__
#define TRUE 1
#define FALSE 0
#define MAX 100
typedef int StackNum;
typedef char StackOp;
typedef struct _num
{
StackNum data;
struct _num *next;
}Num_node;
typedef struct _op
{
StackOp data;
struct _op *next;
}Op_node;
typedef struct _linkStack
{
Num_node *numtop;
Op_node *optop;
}LinkStack;
//创建链式栈
LinkStack * Create_Stack ();
//判断操作数栈空
int StackEmpty_num (LinkStack *s);
//判断运算符栈空
int StackEmpty_op (LinkStack *s);
//进操作数栈
int Push_num (LinkStack *s,StackNum num);
//进运算符栈
int Push_op (LinkStack *s,StackOp op);
//出操作数栈
int Pop_num (LinkStack *s,StackNum *num);
//出运算符栈
int Pop_op (LinkStack *s,StackOp *op);
//获取运算符栈顶元素
int GetTop_op (LinkStack *s,StackOp *op);
//比较运算符优先级
int Cmp_op (LinkStack *s,StackOp op);
//运算
int Operate (LinkStack *s);
//销毁栈
int Destory(LinkStack *s);
#endif //__CALCULATOR_H__
calculator.c
#include <stdlib.h>
#include "calculator.h"
#include "error.h"
//创建链式栈
LinkStack * Create_Stack ()
{
LinkStack * s = (LinkStack *)malloc(sizeof(LinkStack)/sizeof(char));
if (s == NULL)
{
errno = MALLOC_ERROR;
return NULL;
}
s->numtop = NULL;
s->optop = NULL;
return s;
}
//判断操作数栈空
int StackEmpty_num (LinkStack *s)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
return s->numtop == NULL;
}
//判断运算符栈空
int StackEmpty_op (LinkStack *s)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
return s->optop == NULL;
}
//进操作数栈
int Push_num (LinkStack *s,StackNum num)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
Num_node * num_node = (Num_node *)malloc(sizeof(Num_node)/sizeof(char));
if (num_node == NULL)
{
errno = MALLOC_ERROR;
return FALSE;
}
num_node->data = num;
num_node->next = s->numtop;
s->numtop = num_node;
return TRUE;
}
//进运算符栈
int Push_op (LinkStack *s,StackOp op)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
Op_node * op_node = (Op_node *)malloc(sizeof(Op_node)/sizeof(char));
if (op_node == NULL)
{
errno = MALLOC_ERROR;
return FALSE;
}
op_node->data = op;
op_node->next = s->optop;
s->optop = op_node;
return TRUE;
}
//出操作数栈
int Pop_num (LinkStack *s,StackNum *num)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
if (StackEmpty_num (s))
{
errno = EMPTY_STACK;
return FALSE;
}
Num_node *p = s->numtop;
*num = p->data;
s->numtop = p->next;
free(p);
return TRUE;
}
//出运算符栈
int Pop_op (LinkStack *s,StackOp *op)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
if (StackEmpty_op (s))
{
errno = EMPTY_STACK;
return FALSE;
}
Op_node *p = s->optop;
*op = p->data;
s->optop = p->next;
free(p);
return TRUE;
}
//获取运算符栈顶元素
int GetTop_op (LinkStack *s,StackOp *op)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
if (StackEmpty_op (s))
{
errno = EMPTY_STACK;
return FALSE;
}
*op = s->optop->data;
return TRUE;
}
//比较运算符优先级
int Cmp_op (LinkStack *s,StackOp op)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
if (StackEmpty_op (s))
{
return TRUE;
}
StackOp op2;
GetTop_op (s,&op2);
switch (op2)
{
case '+':
{
return TRUE;
}
case '-':
{
if (op == '-' || op == '+')
{
return FALSE;
}
return TRUE;
}
case '*':
{
return FALSE;
}
case '/':
{
return FALSE;
}
default :
return TRUE;
}
}
//运算
int Operate (LinkStack *s)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
if (StackEmpty_op (s))
{
errno = EMPTY_STACK;
return FALSE;
}
StackOp op;
Pop_op (s,&op);
if (op == '(')
{
return FALSE;
}
StackNum num1,num2;
Pop_num (s,&num1);
if (StackEmpty_num (s))
{
Push_num (s,num1);
return FALSE;
}
Pop_num (s,&num2);
StackNum result;
switch (op)
{
case '+':
result = num2 + num1;
break;
case '-':
result = num2 - num1;
break;
case '*':
result = num2 * num1;
break;
case '/':
result = num2 / num1;
break;
default:
return FALSE;
}
Push_num (s,result);
return TRUE;
}
//销毁栈
int Destory(LinkStack *s)
{
if (s == NULL)
{
errno = ERROR;
return FALSE;
}
free(s);
return TRUE;
}
main.c
#include <stdio.h>
#include "calculator.h"
#include "error.h"
#include <stdlib.h>
int main()
{
LinkStack *s = Create_Stack ();
char exp[MAX];
printf ("input an expression:");
fgets(exp,MAX,stdin);
if (exp[0] < '0' || exp[0] > '9')
{
if (exp[0] != '(')
{
errno = INPUT_ERROR;
MyError ("fgets:");
printf ("输入错误,第一个字符应该为数字或“(”\n");
Destory(s);
return FALSE;
}
}
int i = 0;
while (exp[i])
{
if (exp[i] == '\n')
{
exp[i] = '\0';
break;
}
i++;
}
i = 0;
char *p = exp;
char *tmp = p;
int flag = 0;
while (p[i])
{
if (p[i] >= '0' && p[i] <= '9')
{
i++;
flag = 1;
continue;
}
if (flag == 1)
{
Push_num (s,atoi(p));
flag = 0;
}
p = &p[i];
i = 0;
if (p[i] == '(')
{
if (p[i+1] == '+' || p[i+1] == '-' || p[i+1] == '*' || p[i+1] == '/' || p[i+1] == ')')
{
errno = INPUT_ERROR;
MyError ("fgets:");
Destory(s);
return FALSE;
}
Push_op (s,'(');
}
else if (p[i] == ')')
{
while (Operate (s));
}
else
{
if (p[i+1] == '+' || p[i+1] == '-' || p[i+1] == '*' || p[i+1] == '/' || p[i+1] == ')')
{
errno = INPUT_ERROR;
MyError ("fgets:");
Destory(s);
return FALSE;
}
while (Cmp_op (s,p[i]) != TRUE)
{
Operate (s);
}
Push_op (s,p[i]);
}
p = &p[i+1];
tmp = p;
}
if (flag == 1)
{
Push_num (s,atoi(tmp));
}
while (Operate (s));
StackNum result = 0;
Pop_num (s,&result);
printf ("result = %d\n",result);
Destory(s);
return 0;
}
此项目未完善的地方还有很多,特别是对一些错误输入的识别与处理。希望与大家一起完善。