From 6a1918ac8fd0c54a4f81479370e474ccebd56f22 Mon Sep 17 00:00:00 2001 From: Sadeep Madurange Date: Wed, 8 Dec 2021 18:34:01 +0800 Subject: 4.4 --- 4/4.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 4/4.c (limited to '4/4.c') diff --git a/4/4.c b/4/4.c new file mode 100644 index 0000000..6112d82 --- /dev/null +++ b/4/4.c @@ -0,0 +1,143 @@ +#include +#include +#include + +#define MAXOP 100 /* max size of operand or operator */ +#define NUMBER '0' /* signal that a number was found */ +#define MAXVAL 100 /* max depth of val stack */ +#define BUFSIZE 100 + +// commands: +, -, *, /, %, p (prints the top one) +// c (dups top), s (swaps top two), c (clear stack) + +int sp = 0; /* next free stack position */ +double val[MAXVAL]; /* value stack */ + +int bufp = 0; /* next free position in buf */ +char buf[BUFSIZE]; /* buffer for ungetch */ + +/* get next operator or numeric operand */ +int getop(char[]); + +/* push f onto value stack */ +void push(double); + +/* pop and return top value from stack */ +double pop(); + +/* returns a value from stack without removing it */ +double peek(); + +/* reverse Polish calculator with support for modulus operator and negative + * numbers */ +int main(int argc, char *argv[]) { + 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 = pop(); + push(pop() - op2); + break; + case '/': + op2 = pop(); + if (op2 != 0.0) + push(pop() / op2); + else + printf("error: division by zero\n"); + break; + case '%': + op2 = pop(); + if (op2 != 0.0) + push((int)pop() % (int)op2); + else + printf("error: division by zero\n"); + break; + case 'p': + peek(); + break; + case '\n': + printf("\t%.8g\n", pop()); + break; + default: + printf("error: unknown command %s\n", s); + } + } + + return 0; +} + +void push(double f) { + if (sp < MAXVAL) + val[sp++] = f; + else + printf("error: stack empty\n"); +} + +double pop() { + if (sp > 0) + return val[--sp]; + else { + printf("error: stack empty\n"); + return 0.0; + } +} + +double peek() { + if (sp > 0) + return val[sp]; + else { + printf("error: stack empty\n"); + return 0.0; + } +} + +int getch() { + return (bufp > 0) ? buf[--bufp] : getchar(); +} + +void ungetch(int c) { + if (bufp >= BUFSIZE) + printf("ungetch: too many characters\n"); + else + buf[bufp++] = c; +} + +int getop(char s[]) { + int i, c; + + while ((s[0] = c = getch()) == ' ' || c == '\t') + ; + s[1] = 0; + + if (!isdigit(c) && c != '.' && c != '-') + return c; + + i = 0; + if (isdigit(c)) + while (isdigit(s[++i] = c = getch())) + ; + if (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; +} -- cgit v1.2.3