重点在于理解getop函数,利用getch和ungetch来读取字符。返回c或者NUMBER,字符以数组s[]的形式保存
#include<stdio.h>
#include<stdlib.h> //为了使用atof()函数
#define MAXOP 100
#define NUMBER '0'
int getop(char []);//注意必须先声明main用到的函数
void push(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());
break;
case '-': //-和/不满足交换律,先弹出的是被减数放入op2
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':
printf("%.8g\n",pop()); //%g是double型输出
break;
default:
printf("error:unknown command %s\n",s);
break;
}
}
return 0;
}
//定义栈
#define MAXVAL 100
int sp=0; //sp为外部变量,调用后值保存到下一次调用
double val[MAXVAL];
void push(double f){
if(sp<MAXVAL)
val[sp++]=f;
else
printf("error:stack fll,can't push %g\n",f);
}
//弹出并返回栈顶的值
double pop(void){
if(sp>0)
return val[--sp];
else{
printf("error:stack empty\n");
return 0.0;
}
}
//将字符用数组s[]的形式保存
#include<ctype.h>
int getch(void); //提前用到的函数记得声明
void ungetch(int);
int getop(char s[]){
int i,c;
while ((s[0]=c=getch())==' '|| c=='\t') //跳过空格和制表符,getch值给c再给s[0]
;
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) //getch到的下一字符不是结束,返回输入流,下一次读这个
ungetch(c);
return NUMBER;
}
#define BUFSIZE 100
char buf[BUFSIZE]; //ungetch的缓冲区
int bufp=0;
int getch(void){ //缓冲区中有内容则读取,无则直接读输入的
return (bufp>0) ? buf[--bufp]: getchar();
}
void ungetch(int c){ //多读入的字符放入ungetch缓存
if(bufp>=BUFSIZE)
printf("ungetch:too many characters\n");
else
buf[bufp++]=c;
}