逆波兰表示法
在逆波兰表示法中,所有运算符都跟在操作数的后面。比如,下列中缀表达式:
(1-2)*(4+5)
采用逆波兰表示法表示为
1 2 - 4 5 + *
程序结构
while(下一个运算符或操作数不是文件结束指示符)
if(是数)
将该数压入到栈中
else if(是运算符)
弹出所需数目的操作数执行运算
将结果压入到栈中
else if(是换行符)
弹出并打印栈顶的值
else
出错
子程序
字符缓冲 getch/ungetch
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp=0;
getch
缓存区无字符,从外界读取字符 getchar()
缓存区有自付,从缓存区读取字符
int getch(void){
return (bufp>0)?buf[--bufp]:getchar();
}
ungetch
将不属于当前输入的元素存入缓存区,以便后续利用
void ungetch(int c){
if(bufp>=BUFSIZE)
printf("error: too many charaters in buf\n");
else
buf[bufp++]=c;
}
栈压入弹出
#define MAXVAL 100
int sp=0;
double val[MAXVAL];
pop
弹出并返回栈顶的值
double pop(void){
if(sp>0)
return val[--p];
else{
printf("error:stack empty\n");
return 0.0;
}
}
push
void push(int c){
if(sp<MAXVAL)
val[sp++]=c;
else
printf("error:stack full,can't push %g\n",f);
}
获取下一个运算符或操作数 getop
#include<ctype.h>
#define NUMBER '0'
int getch(void);
void ungetch(int);
int getop(s[]){
while((s[0]=c=getch())==' '||c=='\t')
;
s[1]='\0';
if(!isdigit(c)&&c!='.')
return c;
i=0;
if(isdigit(c))
while(isdigit(s[++i]=c=getch()))
;
if(c=='.')
while(isdigit(s[++i]=c=getch()))
;
s[i]='\0';
if(c!=EOF)
ungetch(c);
return NUMBER;
}
逆波兰计算器程序
#include<stdio.h>
#include<stdlib.h>/*为了使用atof()函数*/
#include<ctype.h> /*为了使用isdigit()函数*/
#define MAXOP 100 /*操作数或运算符的最大长度*/
#define NUMBER '0'/*标识找到一个数*/
#define MAXVAL 100/*栈val的最大深度*/
#define BUFSIZE 100/*缓存区*/
double val[MAXVAL];/*操作数寄存的栈*/
int sp = 0; /*下一个空闲栈的位置*/
char buf[BUFSIZE]; /*字符的缓存区*/
int bufp = 0; /*下一个缓冲的位置*/
int getch(void); /*读(缓冲区/外界)字符*/
void ungetch(int); /*将非数字字符压入缓冲区*/
int getop(char s[]);/*下一字符串类别*/
void push(double); /*将转化后的double压入栈*/
double pop(void); /*弹出返回栈顶*/
int main() {
int type;
double op2;
char s[MAXOP];
while ((type = getop(s)) != EOF) {
switch (type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
case'-':
op2 = pop();
push(pop() - op2);
break;
case'/':
op2 = pop();
push(pop() / op2);
case'\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error:unkonwn command %s\n", s);
break;
}
}
return 0;
}
int getch(void) {
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c) {
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
double pop(void) {
if (sp > 0)
return val[--sp];
else {
printf("error:stack empty\n");
return 0.0;
}
}
void push(double f) {
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error:stack full, can't push %g\n", f);
}
int getop(char s[]) {
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c;
i = 0;
if (isdigit(c))
while (isdigit(s[++i] = c = getch()))
;
if (c == '.')
while (isdigit(s[++i] = c = getch()))
;
s[i] = '\n';
if (c != EOF)
ungetch(c);
return NUMBER;
}