这几天有空时就写计算器项目,一开始觉得计算器无非就是简单的加减乘除运算就好了 可是 当我开始着手写程序时
我才发现并不是我想的这么简单 首先你得先输入一串字符串 然后还要判断输入的数字有多大 符号位是什么 如果遇
到括号时该怎么做 等等一系列的问题需要你去好好想一想 一天下来后 总算才有了成功运行的思路 下面就是我的思路
过程 :
(1)找好整个项目程序的架构 一共需要两个栈 一个栈用来存放数字 另一个栈则是存放符号位 在写主函数之前需要
你想把每一个进站出栈以及在这之前的栈的初始化过程写好,不能有一点错误 不然程序将无法正常运行 并且最好考
虑的情况要多些 不能正常运行要有返回值来提醒自己
(2)开始写主函数 因为要将这段字符串的数字和符号一直读完才行所以你就需要先来一个while循环能保持一直在读
取状态 当输入一串字符串后 开始读取数字 每读到一个0~9字符后就计数加一 倘若不是 你就需要判断此时是符号还是
\0的标志 如果是\0的标志 就要使得while循环终止 将你所得到的操作数和符号位分别放到两个栈中
(3)当遇到运算符时 如果它的优先级比运算符栈栈顶元素的优先级高就进栈 空栈的话更不用说 直接进 反之 取出栈
顶运算符和操作数栈栈顶的连续两个操作数进行运算 并将结果存入操作数栈 然后继续比较该运算符与栈顶运算符的
优先级
(4)如果遇到括号的话,左括号一律进运算符栈 右括号一律不进运算符栈 取出运算符栈顶运算符和操作数栈顶的两
个操作数进行运算 并将结果压入操作数栈 直到取出左括号为止。
(5)当字符串读完以后 你会发现有些情况下两个栈里依然会有各自的元素 所以需要你再次进行运算 重复上面的步骤
直到查看符号位栈最顶层为空 则代表所有的输已经全部运行完 这时操作数栈的顶层也就是第一层 即是最后的运算结果
(6)下面就是我写的计算器的代码 有点长 不过思路很清晰 :
#include <stdio.h>
#include <math.h>
#define SIZE 100
#define OK 0
#define ERROR -1
#define ERROR1 -2
typedef double SHUDATA ;
typedef struct
{
SHUDATA shuzi[SIZE] ;//栈操作数数组
int top1 ;
}Caozuoshu ;
typedef char FUDATA ;
typedef struct
{
FUDATA fuhao[SIZE] ;//栈运算符数组
int top2 ;
}Yunsuanfu ;
//置空栈
int InitStack (Caozuoshu *c ,Yunsuanfu *y)
{
if(c==NULL || y==NULL)
{
return ERROR ;
}
c->top1 = -1 ;
y->top2 = -1 ;
return OK ;
}
//判断操作数是否空栈
int StackEmpty1(Caozuoshu *c )
{
if(c==NULL )
{
return ERROR1 ;
}
return (c->top1 == -1);
}
//判断运算符是否空栈
int StackEmpty2( Yunsuanfu *y)
{
if( y==NULL)
{
return ERROR1 ;
}
return (y->top2 == -1) ;
}
//判断操作数是否满栈
int StackFull1(Caozuoshu *c )
{
if(c == NULL )
{
return ERROR ;
}
return (c->top1 == SIZE - 1) ;
}
//判断运算符是否满栈
int StackFull2(Yunsuanfu * y)
{
if( y == NULL)
{
return ERROR ;
}
return (y->top2 == SIZE - 1) ;
}
//数字入栈
int Push1(Caozuoshu *c ,SHUDATA data)
{
if(c == NULL)
{
return ERROR ;
}
if(StackFull1(c))
{
return ERROR ;
}
c->shuzi[++c->top1] = data ;
return OK ;
}
//运算符入栈
int Push2(Yunsuanfu *y ,SHUDATA data)
{
if(y == NULL)
{
return ERROR ;
}
if(StackFull2(y))
{
return ERROR ;
}
y->fuhao[++y->top2] = data ;
return OK ;
}
//获取符号栈顶元素
int GetTop2(Yunsuanfu * y)
{
if(y == NULL)
{
return ERROR ;
}
//判断是否空栈
if(StackEmpty2(y))
{
return ERROR1 ;
}
return y->fuhao[y->top2] ;
}
//获取操作数栈顶元素
int GetTop1(Caozuoshu * c)
{
if(c == NULL)
{
return ERROR ;
}
if(StackEmpty1(c))
{
return ERROR1 ;
}
return c->shuzi[c->top1] ;
}
//操作数出栈
int Pop1(Caozuoshu *c)
{
if(c == NULL)
{
return ERROR ;
}
if(StackEmpty1(c))
{
return ERROR1 ;
}
SHUDATA data = c->shuzi[c->top1--] ;
return data ;
}
//符号数出栈
int Pop2(Yunsuanfu *y)
{
if(y == NULL)
{
return ERROR ;
}
if(StackEmpty2(y))
{
return ERROR1 ;
}
FUDATA data = y->fuhao[y->top2--] ;
return data ;
}
int main()
{
char a1;
double b ;
double c ;
double result ;
Caozuoshu stack1 ;//栈操作数结构体变量
Yunsuanfu stack2 ;//栈运算符结构体变量
if(InitStack (&stack1,&stack2) != OK)
{
return -1 ;
}
/*if(StackEmpty1 (&stack1))
{
printf("是空栈\n") ;
}
else
{
printf("不是空栈\n") ;
}
if(StackEmpty2 (&stack2))
{
printf("是空栈\n") ;
}
else
{
printf("不是空栈\n") ;
} */
char a[20];
scanf("%s",a);
int i = 0;
int temp = 1 ;
while(temp)
{
double count = 0 ;
while(a[i] >= '0' && a[i] <= '9')
{
count++ ;
i++;
}
if(a[i] == '\0' )
{
temp = 0 ;
}
int k ;
double sum = 0 ;
double sum1 ;
double m ;
if(count != 0)
{
for(k=i-count ,m = count - 1;k < i;k++)
{
double n = pow(10.0,m) ;
sum = sum + (a[k] - '0') * n ;
m-- ;
}
if(Push1(&stack1,sum) != OK)
{
return -1 ;
}
}
if((a[i] < '0' || a[i] > '9') && a[i] != '\0')
{
switch (a[i])
{
case '+' :
{
if ( GetTop2(&stack2)=='(' || GetTop2(&stack2)== ERROR1 )
{
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
}
else if(GetTop2(&stack2)== '*' || GetTop2(&stack2)== '/' || GetTop2(&stack2)== '+' || GetTop2(&stack2)== '-')
{
a1 = Pop2(&stack2) ;
b = Pop1(&stack1) ;
c = Pop1(&stack1) ;
switch (a1)
{
case '+' :
{
result = c + b ;
break ;
}
case '-' :
{
result = c - b ;
break ;
}
case '*' :
{
result = c * b ;
break ;
}
case '/' :
{
result = c / b ;
break ;
}
default :
{
printf("对不起 您的操作有误!(1)\n");
break ;
}
}
if(Push1(&stack1,result) != OK)
{
return -1 ;
}
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
}
break ;
}
case '-' :
{
if ( GetTop2(&stack2)=='(' || GetTop2(&stack2)== ERROR1)
{
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
}
else if (GetTop2(&stack2)== '*' || GetTop2(&stack2)== '/' || GetTop2(&stack2)== '+' || GetTop2(&stack2)== '-')
{
a1 = Pop2(&stack2) ;
b = Pop1(&stack1) ;
c = Pop1(&stack1) ;
switch (a1)
{
case '+' :
{
result = c + b ;
break ;
}
case '-' :
{
result = c - b ;
break ;
}
case '*' :
{
result = c * b ;
break ;
}
case '/' :
{
result = c / b ;
break ;
}
default :
{
printf("对不起 您的操作有误!(2)\n");
break ;
}
}
if(Push1(&stack1,result) != OK)
{
return -1 ;
}
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
}
break ;
}
case '*' :
{
if(GetTop2(&stack2)=='(' || GetTop2(&stack2)== ERROR1 || GetTop2(&stack2)== '+' ||GetTop2(&stack2)== '-')
{
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
}
else if(GetTop2(&stack2) == '*' || GetTop2(&stack2) == '/')
{
a1 = Pop2(&stack2) ;
b = Pop1(&stack1) ;
c = Pop1(&stack1) ;
switch (a1)
{
case '+' :
{
result = c + b ;
break ;
}
case '-' :
{
result = c - b ;
break ;
}
case '*' :
{
result = c * b ;
break ;
}
case '/' :
{
result = c / b ;
break ;
}
default :
{
printf("对不起 您的操作有误!(3)\n");
break ;
}
}
if(Push1(&stack1,result) != OK)
{
return -1 ;
}
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
}
break ;
}
case '/' :
{
if(GetTop2(&stack2)=='(' || GetTop2(&stack2)== ERROR1 || GetTop2(&stack2)== '+' ||GetTop2(&stack2)== '-')
{
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
}
else if(GetTop2(&stack2)== '*' || GetTop2(&stack2)== '/')
{
a1 = Pop2(&stack2) ;
b = Pop1(&stack1) ;
c = Pop1(&stack1) ;
switch (a1)
{
case '+' :
{
result = c + b ;
break ;
}
case '-' :
{
result = c - b ;
break ;
}
case '*' :
{
result = c * b ;
break ;
}
case '/' :
{
result = c / b ;
break ;
}
default :
{
printf("对不起 您的操作有误!(4)\n");
break ;
}
}
if(Push1(&stack1,result) != OK)
{
return -1 ;
}
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
}
break ;
}
case '(' :
{
if(Push2(&stack2,a[i]) != OK)
{
return -1 ;
}
break ;
}
case ')' :
{
int temp1 = 1 ;
while(temp1)
{
a1 = Pop2(&stack2) ;
b = Pop1(&stack1) ;
c = Pop1(&stack1) ;
switch (a1)
{
case '+' :
{
result = c + b ;
break ;
}
case '-' :
{
result = c - b ;
break ;
}
case '*' :
{
result = c * b ;
break ;
}
case '/' :
{
result = c / b ;
break ;
}
default :
{
printf("对不起 您的操作有误!(5)\n");
break ;
}
}
if(Push1(&stack1,result) != OK)
{
return -1 ;
}
if(GetTop2(&stack2) != '(')
{
NULL ;
}
else if(GetTop2(&stack2) == '(')
{
temp1 = 0 ;
Pop2(&stack2);
}
}
break ;
}
default :
{
printf("对不起 您的输入有误!\n");
break ;
}
}
}
i = i + 1 ;
}
while(GetTop2(&stack2) != ERROR1)
{
char b1 ;
double b2 ;
double b3 ;
b1 = Pop2(&stack2) ;
b2 = Pop1(&stack1) ;
b3 = Pop1(&stack1) ;
switch (b1)
{
case '+' :
{
result = b3 + b2;
break ;
}
case '-' :
{
result = b3 - b2 ;
break ;
}
case '*' :
{
result = b3 * b2 ;
break ;
}
case '/' :
{
result = b3 / b2 ;
break ;
}
default :
{
printf("对不起 您的操作有误!(6)\n");
break ;
}
}
if(Push1(&stack1,result) != OK)
{
return -1 ;
}
}
printf("最后的结果为:%d\n",Pop1(&stack1));
}