逆ポーランド計算機(C言語)
4043 ワード
逆ポーランドアルゴリズムの表現:すべての演算子がオペランドの後ろに付いています.
(1-2)*(4+5)は1 2-4 5+*と表され、
操作数は左から順にスタックに押し込み、演算子が到着すると、演算子に基づいてスタックから対応する数の操作数を取り出し、結果を計算し、結果をスタックに押し込む.例えば、1、2をスタックに押し込み、次に+に遭遇し、1つの2元オペレータであるため、スタックから2つのオペランドを取り出し、結果を計算し、結果-1をスタックに押し込み、次に4、5をスタックに押し込み、次に*に遭遇し、1つの2元オペレータでもあるので、スタックから2つのオペランド(すなわち5と4)を取り出し、計算結果9をスタックに押し込み、次に*に出会って、まだ1つの2元オペレータで、そこでまたスタックの中から2つの操作数(つまり9と-1)を取り出して、計算結果-9はスタックの中に圧入します.入力行の最後に達すると、スタックの上部の要素が最終的な結果として出力されます.
C言語コード説明:
main.c
getop.c次の演算子またはオペランドを取得し、取得したオペランドを文字配列sに配置し、取得した演算子を直接返す
stack.c入桟、出桟操作を行う(桟に保存されているのは操作数及び演算結果である)
getch.c 1文字取得用
(1-2)*(4+5)は1 2-4 5+*と表され、
操作数は左から順にスタックに押し込み、演算子が到着すると、演算子に基づいてスタックから対応する数の操作数を取り出し、結果を計算し、結果をスタックに押し込む.例えば、1、2をスタックに押し込み、次に+に遭遇し、1つの2元オペレータであるため、スタックから2つのオペランドを取り出し、結果を計算し、結果-1をスタックに押し込み、次に4、5をスタックに押し込み、次に*に遭遇し、1つの2元オペレータでもあるので、スタックから2つのオペランド(すなわち5と4)を取り出し、計算結果9をスタックに押し込み、次に*に出会って、まだ1つの2元オペレータで、そこでまたスタックの中から2つの操作数(つまり9と-1)を取り出して、計算結果-9はスタックの中に圧入します.入力行の最後に達すると、スタックの上部の要素が最終的な結果として出力されます.
C言語コード説明:
main.c
#include
#include // atof
#include "calc.h"
#define MAXOP 100
//atof(char s[]) s ,
main(){
int type;
double op2;
char s[100];
while((type = getop(s)) != EOF) { // s
switch(type) {
case NUMBER: //
push(atof(s));
break;
// ,
case '+':
push(pop() + pop());
printf("+");
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
");
break;
case '
':
printf("\t%.8g
", pop());
break;
// ,
default :
printf("error: unknown command %s
", s);
break;
}
}
return 0;
}
getop.c次の演算子またはオペランドを取得し、取得したオペランドを文字配列sに配置し、取得した演算子を直接返す
#include
#include
#include "calc.h"
//getch()
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] = '\0'; //
if(c != EOF)
ungetch(c);
return NUMBER; //
}
stack.c入桟、出桟操作を行う(桟に保存されているのは操作数及び演算結果である)
#include
#include "calc.h"
#define MAXVAL 100
int sp = 0;
double val[MAXVAL]; //
// f
void push(double f) {
if(sp < MAXVAL) {
//printf("stack ");
val[sp++] = f;
}
else
printf("error: stack full, can't push %g
", f);
}
//
double pop(void) { //void , ,
if(sp > 0)
return val[--sp];
else {
printf("error: stack empty
");
return 0.0;
}
}
getch.c 1文字取得用
#include
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
// ( )
int getch(void) {
//
return (bufp > 0) ? buf[--bufp] : getchar();
}
//
void ungetch(int c) {
if(bufp >= BUFSIZE)
printf("ungetch: too many characters
");
else
buf[bufp++] = c;
}
ungetch() : getch() , , ,ungetch() 。
calc.h
#define NUMBER '0'
//
void push(double);
double pop(void);
int getop(char[]);
int getch(void);
void ungetch(int);
。