#include #include /* для atof() */ #define MAXOP 100 /* макс. размер операнда или оператора */ #define NUMBER '0' /* признак числа */ int getop (char []); void push (double); double pop (void); void optovar(int, double); double vartoop(int); void printstack(void); void printvars(void); /* калькулятор с обратной польской записью */ int main() { int type; double op2; char s[MAXOP]; char in=0; while ((type = getop (s)) != EOF) { switch (type) { case NUMBER: push (atof(s)); break; case '+': push (pop() + pop()); break; case '-': op2 = pop(); push (pop() - op2); break; case '>': in = 1; break; case 'A': case 'B': case 'C': if (in) { optovar(type, pop()); in = 0; } else push(vartoop(type)); break; case 'p': printstack(); break; case 'v': printvars(); break; case '\n': printf("\t%.8g\n", pop()); break; default: printf("ошибка: неизвестная операция %s\n", s); break; } } return 0; } #define MAXVAL 100 /* максимальная глубина стека */ #define MAXVAR 26 /* максимальное количество переменных */ int sp = 0; /* следующая свободная позиция в стеке */ double val[MAXVAL]; /* стек */ double var[MAXVAR]; /* переменные */ /* push: положить значение f в стек */ void push(double f) { if (sp < MAXVAL) val[sp++] = f; else printf("ошибка: стек полон, %g не помещается\n", f); } /* pop: взять с вершины стека и выдать в качестве результата */ double pop(void) { if (sp > 0) return val[--sp]; else { printf ("ошибка: стек пуст\n"); return 0.0; } } /* printstack: печать содержимого стека */ void printstack(void) { int i; printf ("\n"); if (sp > 0) { for (i = 0; i < sp; ++i) printf ("%.8g ", val[i]); } else { printf ("ошибка: стек пуст\n"); } } /* printvars: печать массива переменных */ void printvars(void) { int i; printf ("\n"); for (i = 0; i < MAXVAR; ++i) printf ("%.8g ", var[i]); } /* optovar: поместить верхнюю ячейку стека в переменную */ void optovar(int n, double f) { var[n-'A'] = f; } /* vartoop: взять значение переменной и выдать в качестве результата */ double vartoop(int n) { return var[n-'A']; } #include int getch(void); void ungetch(int); /* getop: получает следующий оператор или операнд */ int getop(char s[]) { int i=0, c, t; while ((s[i] = c = getch()) == ' ' || c == '\t'); if (!isdigit(c) && c != '.'){ if (c == '-') { if (isdigit(t = getch()) || t == '.') { c = t; s[++i] = c; } else { ungetch(t); return c; /* не число */ } } else { return c; /* не число */ } } 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; } #define BUFSIZE 100 char buf[BUFSIZE]; /* буфер для ungetch */ int bufp = 0; /* след. свободная позиция в буфере */ int getch(void) /* взять (возможно возвращенный) символ */ { return (bufp > 0) ? buf[--bufp] : getchar(); } void ungetch(int c) /* вернуть символ на ввод */ { if (bufp >= BUFSIZE) printf("ungetch: слишком много символов\n"); else buf[bufp++] = c; }