26
Reverse Polish Calculator • Reverse Polish Notation 연연연연 연연연연연 연연 연연 . 연 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 연연연연 연연연 연연연연 연연연 . ( 연연연 연연연연 연연 )

Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

Embed Size (px)

Citation preview

Page 1: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

Reverse Polish Calculator

• Reverse Polish Notation 연산자가 피연산자의 뒤에 온다 . 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다 . ( 수식이 애매하지 않다 )

Page 2: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

• 구현 방법 1) 피연산자는 stack(LIFO) 상에 push 2) 연산자가 입력되면 적절한 수의 피연산자를 pop

시킨다 . ( 이항연산자 2 개 ) 3) 연산자를 pop 된 피연산자에 적용하고 , 그 계산

결과를 stack 상에 push

예 ) 1 2 – 4 5 + * 1) 1 과 2 는 stack 상에 push 2) – 를 만나면 stack 상의 2 개 자료를 pop 3) 이들의 차를 구한 (-1) 다음 이 결과값을 stack 에 push

Page 3: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

• 1’) 4 와 5 를 stack 상에 push 2’) + 를 만날 때 , stack 상의 2 개의 자료를 pop 3’) 4 와 5 를 더한 다음 그 결과 9 를 stack 상에 push 2’’) * 를 만나면 stack 상의 2 개의 자료를 pop (-1 과 9) 3’’) –1 과 9 를 곱한 다음 그 결과 – 9 를 stack 에 push * newline 을 만나면 stack 상의 자료를 pop 한 다음 출력한다 .

Page 4: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

• 실행 과정 1 2 – 4 5 + *

stack

0sp 1

2

sp

-1

sp

-1

4

5

sp

-1

9

sp

-9

sp

sp

Page 5: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

개략적인 프로그램 구성While (next operator or operand is not EOF)

if (number)push it

else if (operator)pop operandsdo operationpush result

else if (newline)pop and print top of stack

elseerror

Page 6: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

#define MAXOP 100#define NUMBER '0'

int getop(char []);void push(double);double pop(void);

/* reverse polish calculator */main() {

int type;double op2;char s[MAXOP];

Page 7: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

while ((type = getop(s)) != EOF) {switch (type) {case NUMBER:

push(atof(s));break;

case '+':push(pop() + pop());break;

case '*':push(pop() * pop());break;

Page 8: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

case '-':op2 = pop();push(pop() - op2);break;

case '/':op2 = pop();if (op2 != 0.0)

push(pop() / op2);else

printf("erroe: zero division\n");break;

Page 9: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

case '\n':printf("\t%.8g\n",pop());break;

default:printf("error: unknown command %s\n",s);

break;}

}return 0;

}

Page 10: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

#define MAXVAL 100int sp = 0;double val[MAXVAL];

void push(double f) {if (sp < MAXVAL )

val[sp++] = f;else

printf("error: stack full, can't push %g\n", f);

}

Page 11: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

double pop(void) {if (sp > 0)

return val[--sp];else {

printf("error: stack empty\n");return 0.0;

}}

Page 12: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

#include <ctype.h>

int getch(void);void ungetch(int);

/* getop: get next operator or numeric operand */

int getop(char s[]) {int i, c;

while ((s[0] = c = getch()) == ' ' || c == '\t');

Page 13: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

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()))

;

Page 14: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

s[i] = '\0';if (c != EOF)ungetch(c);return NUMBER;

}#define BUFSIZE 100

char buf[BUFSIZE];int bufp = 0;

int getch(void) {return (bufp > 0) ? buf[--bufp] : getchar();

}

Page 15: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

void ungetch(int c) {if (bufp >= BUFSIZE)

printf("ungetch: too many characters\n");else

buf[bufp++] = c;}

Page 16: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

Scope rule( 유효범위 규칙 )main() { …}

/**********************************/

int sp = 0;

double val[MAXVAL];

void push(double f) { … }

double pop(void) { …}

sp, val 변수의 scope : 선언된 위치부터 파일의 끝까지 (push, pop 에서 ok, main 에서 X, main 내에서 push 나 pop 도 X)

Page 17: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

• 전역변수가 정의되기 전에 사용될 필요가 있거나 , 다른 파일에서 정의된다면 extern 선언이 반드시 요구됨 .

• 선언 (declaration) vs 정의 (definition) 선언 : 변수의 속성 ( 타입 ) 을 지시 정의 : 기억장소 할당 예 ) 정의int sp;double val[MAXVAL];

예 ) 선언extern int sp;extern double val[];

Page 18: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

• 예

In file1:

extern int sp;

extern double val[];

void push(double f) { … }

double pop(void) { … }

In file2:

int sp = 0;

double val[MAXVAL];

Page 19: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

Separate Compile

• Let us now consider dividing the calculator program into several source files.

• 1st file : main (main.c)• 2nd file : push, pop (stack.c)• 3rd file : getop (getop.c)• 4th file : getch, ungetch (getch.c)

Page 20: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

#define NUMBER ‘0’

void push(double);

double pop(void);

int getop(char []);

int getch(void);

void ungetch(int);

calc.h

Separate Compile

#include <stdio.h>

#inlcude <math.h>

#include “calc.h”

#define MAXOP 100

main() { … }

main.c

Page 21: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

getop.c

#include <stdio.h>

#include <ctype.h>

#include “calc.h”

int getop() { … }

stack.c

#include <stdio.h>

#include “calc.h”

#define MAXVAL 100

int sp = 0;

double val[MAXVAL];

void push(double) { …}

double pop(void) { … }

Separate Compile

Page 22: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

Separate Compile

getch.c

#include <stdio.h>

#define BUFSIZE 100

char buf[BUFSIZE];

int bufp = 0;

int getch(void) { … }

void ungetch(int c) { … }

Page 23: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

Turbo-C( 분리컴파일 )

• Create the file rcalc.prj and put into it the name of each file that contains definitions of functions used in the program. The names may be separated by white space, commas, or semicolons.

• In file rcalc.prj: main.c (calc.h) getop.c (calc.h) stack.c (calc.h) getch.c(calc.h)

Page 24: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

• Select the Project menu from main menu line.

• Then in turn select Project name and type in the name rcalc.prj

• Now press Alt-r to make and run the program.

• Turbo-C project facility will recompile only those files that have been changed since the last time rcalc.exe was updated.

Page 25: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

Static 변수 사용 예• Static 변수의 선언은 컴파일되는

파일의 나머지 부분에 대해서만 scope를 제약하는 기능

• 예 static char buf[BUFSIZE]; static int bufp = 0; int getch(void) { … }

Page 26: Reverse Polish Calculator Reverse Polish Notation 연산자가 피연산자의 뒤에 온다. 예 ) (1 – 2) * (4 + 5) 1 2 – 4 5 + * * 수식에서 괄호가 요구되지 않는다

C 전처리기1. File inclusion #include “filename” #include <filename>2. Macro 대치 #define name replacement text #define forever for(;;) #define max(A,B) ((A) > (B) ? (A) : (B)) #define square(x) ( (x) * (x) )