|
Fri, May 09, 2008
![[Link]](http://geekblog.oneandoneis2.org/img/chain_link.gif)
Add the ability to use variables to your calculator.
In a stroke of genius, I initially created a way to assign variables, but forgot to also install a way of calling them. Sigh.
The C answer book redeemed itself a little. After using strcmp in the previous example, when we're still 30-odd pages away from learning its existence, I was not impressed with it. But I thought I was going to have to replace the switch statement with if-else's to be able to do case 'A': case 'B': case 'C':... etc, but it made me realize that putting an 'if' into the 'default:' would solve this one far more easily.
I was also going to create 26 separate variables in the code for the 26 variables in the code, because I hadn't thought enough about it. Creating one array of 26 was of course a much better solution.
Not sure I'll bother with any more of the coding exercises before moving onto the next section.. none leap out at me as particularly interesting. We shall see...
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXOP 100
#define NUMBER '0'
#define LOSE 0
#define KEEP 1
#define SWAP 2
#define CLEAR 3
int getop(char []);
void push(double);
double pop(int);
int main ()
{
int type;
double op2;
char s[MAXOP];
double v[26];
double lastval = 0;
for (op2 = 0; op2 < 26; op2++)
v[(int) op2] = 0;
printf("Welcome to Dominic's reverse Polish notation calculator\n");
printf("Commands:\n\t+ - * / %% are standard\n");
printf("\t? displays topmost stack value\t-\td duplicates topmost value\
n");
printf("\tx clears the stack\t-\te exchanges the two topmost values\n");
printf("\ts, c, t perform sin, cos, and tan operations respectively\n");
printf("\tp raises to the power of the topmost number the preceeding num
ber\n");
while ((type = getop(s)) != EOF) {
switch (type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop(LOSE) + pop(LOSE));
break;
case '*':
push(pop(LOSE) * pop(LOSE));
break;
case '-':
op2 = pop(LOSE);
push(pop(LOSE) - op2);
break;
case '/':
op2 = pop(LOSE);
if (op2 != 0.0)
push(pop(LOSE) / op2);
else
printf("error: zero divisor\n");
break;
case '%':
op2 = pop(LOSE);
if (op2 != 0.0)
push((int) pop(LOSE) % (int) op2);
else
printf("error: zero divisor\n");
break;
case '\n':
printf("\t%.8g\n", (lastval = pop(LOSE)));
break;
case '?': /* Display topmost stack item */
printf("\t%.8g\n", (lastval = pop(KEEP)));
break;
case 'd': /* Duplicate topmost stack item */
push(pop(KEEP));
break;
case 'x': /* Clear stack */
pop(CLEAR);
printf("\tStack cleared\n");
break;
case 'e': /* Switch topmost two stack items */
pop(SWAP);
break;
case 's':
push(sin(pop(LOSE)));
break;
case 'c':
push(cos(pop(LOSE)));
break;
case 't':
push(tan(pop(LOSE)));
break;
case 'p':
op2 = pop(LOSE);
push(pow(pop(LOSE),op2));
break;
case 'v':
push(lastval);
break;
case '=':
op2 = getop(s);
if (op2 >= 'A' && op2 <= 'Z')
v[((int) op2 - 'A')] = pop(LOSE);
else
printf("\tBad variable name\n");
break;
default:
if (type >= 'A' && type <= 'Z')
push(v[(type - 'A')]);
else
printf("error: unknown command %s\n", s)
;
break;
}
}
return 0;
}
#define MAXVAL 100
int 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);
}
double pop(int i)
{
double j;
if (sp > 0) {
if (i == LOSE)
return val[--sp];
else if (i == KEEP)
return val[(sp - 1)];
else if (i == SWAP) {
j = val[(sp - 1)];
val[(sp - 1)] = val[(sp - 2)];
val[(sp - 2)] = j;
return 0.0;
}
else if (i == CLEAR) {
sp = 0;
return 0.0;
}
else
return 0.0;
}
else {
printf("error: stack empty\n");
return 0.0;
}
}
#include <ctype.h>
int getch(void);
void ungetch(int);
int getop(char s[])
{
int i,c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.' && c != '-')
return c; /* Not a number */
i = 0;
if (c == '-') { /* Deal with negative numbers */
if (isdigit(c = getch()) || c == '.')
s[++i] = c;
else {
if (c != EOF)
ungetch(c);
return '-';
}
}
if (c == '-') { /* Deal with negative numbers */
if (isdigit(c = getch()) || c == '.')
s[++i] = c;
else {
if (c != EOF)
ungetch(c);
return '-';
}
}
if (isdigit(c)) /* Collect integer part */
while (isdigit(s[++i] = c = getch()))
;
if (c == '.') /* Collect fraction part */
while (isdigit(s[++i] = c = getch()))
;
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();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
| Mon | Tue | Wed | Thu | Fri | Sat | Sun |
|---|---|---|---|---|---|---|
| << < | > >> | |||||
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |