Skip to content

Commit bda77ac

Browse files
committed
improve answer
1 parent 8925de3 commit bda77ac

File tree

1 file changed

+80
-76
lines changed

1 file changed

+80
-76
lines changed

chapter04/4-10.c

Lines changed: 80 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,32 @@
66
*/
77

88
#include <stdio.h>
9-
#include <stdlib.h> /* for atof() */
9+
#include <stdlib.h> /* for atof() */
1010
#include <ctype.h>
11-
#include <string.h> /* for strcmp() */
12-
#include <math.h> /* for math commands */
13-
14-
#define MAXLINE 1000
15-
#define MAXOP 100 /* max size of operand or operator */
16-
#define NUMBER '0' /* signal that a number was found */
17-
#define MATH '1' /* signal that an operation was found */
18-
#define MAXVAL 100 /* maximum depth of val stack */
19-
#define BUFSIZE 100
20-
#define MAXVAR 26
21-
#define TOP val[sp - 1] /* top element in stack */
11+
#include <string.h> /* for strcmp() */
12+
#include <math.h> /* for math commands */
13+
14+
#define MAXLINE 1000
15+
#define MAXOP 100 /* max size of operand or operator */
16+
#define NUMBER '0' /* signal that a number was found */
17+
#define NAME '1' /* signal that a string command was found */
18+
#define MAXVAL 100 /* maximum depth of val stack */
19+
#define BUFSIZE 100
20+
#define MAXVAR 26
21+
#define TOP val[sp - 1] /* top element in stack */
2222

2323
/* functions */
2424
int getop(char []);
2525
int getLine(char [], int);
2626
void push(double);
2727
double pop(void);
28-
void printTop(void);
28+
void printTOP(void);
2929
void duplicateTop(void);
3030
void swapTopTwo(void);
3131
void clearStack(void);
3232
int mathfunction(char []);
3333
void storeVariable(void);
34-
void fetchVariable(void);
34+
void fetchVariable(int var);
3535
void clearMemory(void);
3636

3737
/* globals */
@@ -40,9 +40,9 @@ double val[MAXVAL]; /* value stack */
4040
double mem[MAXVAR]; /* variables values */
4141
char buf[BUFSIZE]; /* buffer from ungetch */
4242
int bufp; /* next free position in buf */
43-
int stackcmd; /* stack commands flag */
44-
char variable; /* current input variable */
45-
double lastPrint; /* last printed value */
43+
int peak; /* flag: peak at top of the stack */
44+
int variable; /* current input variable */
45+
double printed; /* last printed value */
4646

4747
/* push: push f onto value stack */
4848
void push(double f)
@@ -71,7 +71,7 @@ int getop(char s[])
7171
static char line[MAXLINE]; /* note static in type */
7272
int j;
7373

74-
if (i == len) { /* previous was read completely */
74+
if (i == len) { /* previous line read completely */
7575
len = getLine(line, MAXLINE);
7676
if (!len)
7777
return EOF;
@@ -89,7 +89,7 @@ int getop(char s[])
8989
while (isalpha(line[i]))
9090
s[j++] = line[i++];
9191
s[j] = '\0';
92-
return MATH;
92+
return (strlen(s) == 1) ? s[0] : NAME;
9393
}
9494

9595
if (!isdigit(line[i]) && line[i] != '.')
@@ -124,98 +124,96 @@ int getLine(char s[], int lim)
124124
return i;
125125
}
126126

127-
/* printTop: prints the top element in the stack */
128-
void printTop(void)
127+
/* printTOP: print top of the stack without pop */
128+
void printTOP(void)
129129
{
130-
if (sp > 0) {
131-
printf("\t%.8g\n", TOP);
132-
stackcmd = 1;
133-
}
130+
if (sp < 1)
131+
printf("stack empty\n");
132+
printf("\t%.8g\n", TOP);
134133
}
135134

136-
/* deleteTop: deletes the top element in the stack */
135+
/* duplicateTop: duplicate the top element in the stack */
137136
void duplicateTop(void)
138137
{
139-
if (sp > 0) {
140-
push(TOP);
141-
printTop();
142-
}
138+
double top;
139+
140+
if (sp < 1)
141+
return;
142+
push(top = pop());
143+
push(top);
143144
}
144145

145146
/* swapTopTwo: swaps top two elements */
146147
void swapTopTwo(void)
147148
{
148149
double top1, top2;
149150

150-
if (sp > 1) {
151-
top1 = pop();
152-
top2 = pop();
153-
push(top1);
154-
push(top2);
155-
printTop();
151+
if (sp < 2) {
152+
if (sp == 1)
153+
printf("error: 1 element in stack\n");
154+
return;
156155
}
156+
top1 = pop();
157+
top2 = pop();
158+
push(top1);
159+
push(top2);
157160
}
158161

159162
/* clear: clears the entire stack */
160163
void clearStack(void)
161164
{
162-
while (sp > 0)
165+
while (sp > 1)
163166
pop();
164-
printTop();
165167
}
166168

167-
/* mathf: call the appropriate math function according to value of s */
169+
/* mathfunction: call the appropriate math function according to value of s,
170+
* return 1 on success 0 on failure. */
168171
int mathfunction(char s[])
169172
{
170173
double op2;
171174

172-
if (strcmp(s, "sin") == 0)
175+
if (!strcmp(s, "sin"))
173176
push(sin(pop()));
174-
else if (strcmp(s, "cos") == 0)
177+
else if (!strcmp(s, "cos"))
175178
push(cos(pop()));
176-
else if (strcmp(s, "exp") == 0)
179+
else if (!strcmp(s, "exp"))
177180
push(exp(pop()));
178-
else if (strcmp(s, "sqrt") == 0)
181+
else if (!strcmp(s, "sqrt"))
179182
push(sqrt(pop()));
180-
else if (strcmp(s, "pow") == 0) {
183+
else if (!strcmp(s, "pow")) {
181184
op2 = pop();
182185
push(pow(pop(), op2));
183186
} else
184187
return 0;
185188
return 1;
186189
}
187190

188-
/* storeVariable: stores the value of a variable (a to z) to the corrosponding
189-
* memory location in mem */
191+
/* storeVariable: store variable value (a to z) to the corresponding
192+
* location in mem and push back to top of stack */
190193
void storeVariable(void)
191194
{
192-
pop(); /* pop stored value by fetchVariable */
193-
variable = tolower(variable);
194-
mem[variable - 'a'] = pop(); /* variable value - top of the stack */
195-
stackcmd = 1; /* skip pop print */
195+
// if (isalpha(variable) && islower(variable)) {
196+
if (variable >= 'a' && variable <= 'z') {
197+
pop();
198+
push(mem[variable - 'a'] = pop());
199+
} else
200+
printf("error: no variable name\n");
196201
}
197202

198-
/* fetchVariable: fetches variable value from memory and pushes to the top of
199-
* the stack */
200-
void fetchVariable(void)
203+
/* fetchVariable: fetch var value from mem and push on to value stack */
204+
void fetchVariable(int var)
201205
{
202-
if (variable == 'R')
203-
push(lastPrint);
204-
else {
205-
variable = tolower(variable);
206-
push(mem[variable - 'a']);
207-
}
206+
push(mem[var - 'a']);
208207
}
209208

210-
/* clearMemory: initializes values of mem to 0 */
209+
/* clearMemory: set values of mem to 0 */
211210
void clearMemory(void)
212211
{
213212
int i;
214213

215214
for (i = 0; i <= MAXVAR; ++i)
216215
mem[i] = 0;
217216
printf("memory cleared\n");
218-
stackcmd = 1; /* skip pop print */
219217
}
220218

221219
/* reverse Polish Calculator */
@@ -224,12 +222,21 @@ int main(void)
224222
int type;
225223
double op2;
226224
char s[MAXOP];
227-
225+
228226
while ((type = getop(s)) != EOF) {
229227
switch (type) {
230228
case NUMBER:
231229
push(atof(s));
232230
break;
231+
case NAME:
232+
if (!strcmp(s, "lp")) {
233+
push(printed);
234+
} else if (!strcmp(s, "mc")) {
235+
clearMemory();
236+
peak = 1;
237+
} else if (!mathfunction(s))
238+
printf("error: unknown command %s\n", s);
239+
break;
233240
case '+':
234241
push(pop() + pop());
235242
break;
@@ -255,7 +262,7 @@ int main(void)
255262
printf("error: zero divisor\n");
256263
break;
257264
case '!':
258-
printTop();
265+
peak = 1;
259266
break;
260267
case '#':
261268
duplicateTop();
@@ -270,23 +277,20 @@ int main(void)
270277
storeVariable();
271278
break;
272279
case '\n':
273-
if (!stackcmd)
274-
printf("\t%.8g\n", lastPrint = pop());
275-
stackcmd = 0;
276-
break;
277-
case MATH:
278-
if (strlen(s) == 1) {
279-
variable = s[0];
280-
fetchVariable();
281-
} else if (strcmp(s, "mc") == 0)
282-
clearMemory();
283-
else if (!mathfunction(s))
284-
printf("error: unknown command %s\n", s);
280+
if (peak) {
281+
printTOP();
282+
peak = 0;
283+
} else
284+
printf("\t%.8g\n", printed = pop());
285285
break;
286286
default:
287-
printf("error: unknown command %s\n", s);
287+
if (islower(type))
288+
fetchVariable(type);
289+
else
290+
printf("error: unknown command %s\n", s);
288291
break;
289292
}
293+
variable = type; /* remember variable */
290294
}
291295
return 0;
292296
}

0 commit comments

Comments
 (0)