main.c
#include <stdlib.h> //为了使用atof函数
#include <stdio.h>
#include <math.h>
#include "op.h"
#include "stack.h"
#define MAXOP 100 //操作数或运算符的最大长度
#define NUMBER '0' // 标识找到一个数
// S-sin E-exp P-pow
int getop(char []);
void push(double);
double pop(void);
//逆波兰计算器
int main(void)
{
int type;
double op2,op1,copy,temp,var,print;
char s[MAXOP];
int state=0;
int state_1=0;
char ch;
while((type=getop(s))!=EOF){
switch(type){
case NUMBER:
push(atof(s));
break;
case '+':
push(pop()+pop());
break;
case '*':
push(pop()*pop());
break;
case '-':
op2=pop();
push(pop()-op2);
break;
case '/':
op2=pop();
if(op2!=0.0)
push(pop()/op2);
else
printf("error: zero divisor\n");
break;
case '\n':
if(state==0){ //状态机 针对栈的操作再输入对应操作符之后需要输入'\n' 这里的'\n'不能打印出栈元素
print=pop();
push(print);
printf("\t%.8g\n",pop()); //回车键 打印栈顶元素 (出栈)
}
else
state=0; //恢复原状态
break;
case 'p': //不弹出元素的情况下打印栈顶元素
op2=pop(); //弹出栈顶
printf("\t栈顶元素%.8g\n",op2);
push(op2); //压回栈顶
state=1;
break;
case 'c': //复制栈顶元素到copy
op2=pop();
copy=op2;
push(op2);
printf("You have copied the top element of stack to the variable copy : copy= %.8g\n",copy);
state=1;
break;
case 'd': //交换栈顶两个元素的值
op1=pop();
op2=pop();
push(op1);
push(op2);
printf("You have change the first two element of stack,use 'p' to check it.\n");
state=1;
break;
case 't':// 清空栈
clear();
state=1;
break;
case 'S': //正弦
push(sin(pop()));
break;
case 'E': //exp
push(exp(pop()));
break;
case 'P': //power
op2=pop();
push(pow(pop(),op2));
break;
case 'v': //变量按钮 变量模块 (本来想函数化的,牵扯到状态机没成功)
if(state_1==0){
state_1=1;
printf("请为变量var赋值:\n");
scanf("%lf",&var); //scanf函数读入double类型 %lf 否则会出错
state=1;
break;
}
if(state_1==1){
if((ch=getchar())=='a'&&(ch=getchar())=='r'){
//state=1;
push(var);
break;
}
else
printf("\terror\n");
state_1=0;
break;
}
case 's': // 查看最近打印的值
printf("最近打印的值%g\n",print);
state=1;
break;
case '%':
op2=pop();
if(((op1=pop())==(int)op1)&&(op2==(int)op2)&&(op2!=0.0)){
push((int)op1%(int)op2);
}
else
printf("zero divisor or there is a float\n");
break;
default:
printf("error: unknown comand %s\n",s);
break;
}
}
return 0;
}
头文件
“op.h”
#include<ctype.h>
#define NUMBER '0' // 标识找到一个数
#define MAXVAL 100 //栈val的最大深度
int getch(void);
void ungetch(int);
/*getop函数:获取下一个运算符或数值操作数*/
int getop(char s[])
{
int i,c,sign=1;
while((s[0]=c=getchar())==' '||c=='\t')
;
s[1]='\0';
if(!isdigit(c)&&c!='.'&&c!='-'){
return c; //不是数 也不是'-'
}
i=0;
if(isdigit(c)||c=='-'){
while(isdigit(s[++i]=c=getch()))
;
if(c == '-')
if(isdigit(c = getch()) || c == '.') //表明是负号
s[++i] = c;
else
{
if(c != EOF)
ungetch(c);
return '-'; // 表明是减号
}
}
if(c=='.')
while(isdigit(s[++i]=c=getch()))
;
s[i]='\0';
if(c!=EOF)
ungetch(c);
return NUMBER;
}
#define BUFSIZE 100
char buf[BUFSIZE]; //用于ungetch函数的缓冲区
int bufp = 0; //buf中下一个空闲位置
int getch(void) //取一个字符
{
return (bufp>0? buf[--bufp]:getchar());
}
void ungetch(int c)
{
if(bufp>=BUFSIZE)
printf("Too many characters\n");
else
buf[bufp++]=c;
}
“stack.h”
int sp=0;//下一个空栈的位置
double val[MAXVAL]; //值栈
//push函数:把 f 压到值栈中
void push(double(f))
{
if(sp<MAXVAL)
val[sp++]=f;
else
printf("error: stack full, can't push%g\n",f);
}
//pop函数: 弹出并返回栈顶的值
double pop(void)
{
if(sp>0)
return val[--sp];
else{
printf("error: stack empty\n");
return 0.0;
}
}
void clear(void)
{
sp=0;
}