I have been learning C with K&R Book 2nd Ed. And well, so far I've gotten to chapter five, and I've been dealing with pointers/command line arguments.
I came up with the following solution for the exercise (Chapter 5, Ex-5.10):
Exercise 5-10. Write the program expr, which evaluates a reverse Polish expression from the command line, where each operator or operand is a separate argument. For example, expr 2 3 4 + * evaluates 2 x (3 + 4).
I would like to know how to improve it.:
/*-
* Exercise 5-10. Write the program expr, which evaluates a reverse Polish
* expression from the command line, where each operator or operand is a separate
* argument. For example,
*
* expr 2 3 4 + *
*
* evaluates 2 x (3 + 4).
*
* By jr.chavez
*
* NOTE:
* To receive the expected output with the following example:
* 2 3 4 + *
* '\' must be used (e.g., 2 3 4 + \* instead of *)
*/
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <string.h> /* for strlen() */
#include <ctype.h> /* for isdigit() */
#define NUMBER '0' /* signal that a number was found */
#define MAXVAL 100 /* next free stack position */
static int sp = 0; /* next free stack position */
static double val[MAXVAL]; /* value stack */
void push(double);
double pop(void);
/* reverse Polish calculator */
int
main(int argc, char *argv[])
{
int type, c;
double op2;
while (--argc > 0) {
{
char *p = *++argv;
type = (!isdigit(c = *p) && strlen(p) == 1) ? c : NUMBER;
}
switch (type) {
case NUMBER:
push(atof(*argv));
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
fprintf(stderr, "error: zero divisor\n");
break;
default:
fprintf(stderr, "error: unkown command %s\n", *argv);
argc = 1;
break;
}
}
printf("\t%.8g\n", pop());
return 0;
}
/* push: push f onto value stack */
void
push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
fprintf(stderr, "error: stack full, can't push %g\n", f);
}
/* pop: pop and return top value from stack */
double
pop(void)
{
if (sp > 0)
return val[--sp];
else {
fprintf(stderr, "error: empty stack\n");
return 0.0;
}
}
input:
./bin/main 2 3 4 + \*
output:
14
Note: I decided not to add options like sin, cos, exp, and pow.