Skip to content

Commit 4e3551a

Browse files
committed
code cleanup
1 parent c6e442a commit 4e3551a

File tree

7 files changed

+424
-389
lines changed

7 files changed

+424
-389
lines changed

chapter04/4-10.c

Lines changed: 99 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,46 @@
11
/*
2-
* Exercise 4-10. An alternate organization uses getline to read an entire input
3-
* line; this makes getch and ungetch unnecessary. Revise the calculator to us
4-
* this approach.
2+
* Exercise 4-10. An alternative organization uses getline to read an entire
3+
* input line; this makes getch and ungetch unnecessary. Revise the calculator
4+
* to use this approach.
55
* Faisal Saadatmand
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 */
11+
#include <string.h> /* for strcmp() */
12+
#include <math.h> /* for math commands */
1313

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 END 0 /* signal EOF */
19-
#define MAXVAL 100 /* maximum depth of val stack */
20-
#define MATCH 0
21-
#define MAXVAR 26 /* max number of variables */
22-
#define TOP val[sp - 1] /* top of the stack element */
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 */
2322

2423
/* functions */
2524
int getop(char []);
2625
int getLine(char [], int);
2726
void push(double);
2827
double pop(void);
2928
void printTop(void);
30-
void duplicateTop (void);
29+
void duplicateTop(void);
3130
void swapTopTwo(void);
3231
void clearStack(void);
33-
void storeVariable(double [], char);
34-
void fetchVariable(double [], char);
35-
void clearMemory(double [], int);
32+
int mathfunction(char []);
33+
void storeVariable(void);
34+
void fetchVariable(void);
35+
void clearMemory(void);
3636

3737
/* globals */
38-
int sp = 0; /* next free stack position */
38+
int sp; /* next free stack position */
3939
double val[MAXVAL]; /* value stack */
40+
double mem[MAXVAR]; /* variables values */
41+
char buf[BUFSIZE]; /* buffer from ungetch */
42+
int bufp; /* next free position in buf */
43+
int stackcmd; /* stack commands flag */
4044
char variable; /* current input variable */
4145
double lastPrint; /* last printed value */
4246

@@ -52,44 +56,46 @@ void push(double f)
5256
/* pop: pop and return top value from stack */
5357
double pop(void)
5458
{
55-
if (sp > 0) {
59+
if (sp > 0)
5660
return val[--sp];
57-
} else {
61+
else {
5862
printf("error: stack empty\n");
5963
return 0.0;
6064
}
6165
}
6266

63-
/* getop: get next operator or numeric operand */
67+
/* getop: get next operator or numeric operand - getline version */
6468
int getop(char s[])
6569
{
6670
static int i, len; /* note static in type */
6771
static char line[MAXLINE]; /* note static in type */
6872
int j;
6973

70-
if (i == len) { /* check if the previous line was read completely */
71-
len = getLine(line, MAXLINE); /* read the next line */
72-
i = 0; /* reset index */
73-
if (len < 0) /* line to read */
74-
return END;
74+
if (i == len) { /* previous was read completely */
75+
len = getLine(line, MAXLINE);
76+
if (!len)
77+
return EOF;
78+
i = 0; /* reset line index */
7579
}
7680

7781
j = 0;
7882
while (isblank(line[i])) /* skip blanks */
7983
++i;
8084

81-
if (line[i] == '-' && isdigit(line[i + 1])) /* negative numbers */
85+
if (line[i] == '-' && isdigit(line[i + 1])) /* sign */
8286
s[j++] = line[i++];
8387

84-
if (!isdigit(line[i]) && !isalpha(line[i]) && line[i] != '.')
85-
return line[i++]; /* not a number */
86-
8788
if (isalpha(line[i])) { /* math functions and variables */
8889
while (isalpha(line[i]))
8990
s[j++] = line[i++];
9091
s[j] = '\0';
9192
return MATH;
92-
} else if (isdigit(line[i])) /* collect number */
93+
}
94+
95+
if (!isdigit(line[i]) && line[i] != '.')
96+
return line[i++]; /* not a number */
97+
98+
if (isdigit(line[i])) /* collect number */
9399
while (isdigit(line[i]))
94100
s[j++] = line[i++];
95101

@@ -118,23 +124,25 @@ int getLine(char s[], int lim)
118124
return i;
119125
}
120126

121-
/* printTop: prints the top element in the stack without popping */
127+
/* printTop: prints the top element in the stack */
122128
void printTop(void)
123129
{
124-
if (sp > 0)
130+
if (sp > 0) {
125131
printf("\t%.8g\n", TOP);
126-
else
127-
printf("stack is empty\n");
132+
stackcmd = 1;
133+
}
128134
}
129135

130-
/* duplicateTop: duplicate the top element in the stack */
131-
void duplicateTop (void)
136+
/* deleteTop: deletes the top element in the stack */
137+
void duplicateTop(void)
132138
{
133-
if (sp > 0)
139+
if (sp > 0) {
134140
push(TOP);
141+
printTop();
142+
}
135143
}
136144

137-
/* swapTopTwos: swaps top two elements */
145+
/* swapTopTwo: swaps top two elements */
138146
void swapTopTwo(void)
139147
{
140148
double top1, top2;
@@ -144,54 +152,70 @@ void duplicateTop (void)
144152
top2 = pop();
145153
push(top1);
146154
push(top2);
147-
} else
148-
printf("not enough elements\n");
149-
}
155+
printTop();
156+
}
157+
}
150158

151159
/* clear: clears the entire stack */
152160
void clearStack(void)
153161
{
154162
while (sp > 0)
155163
pop();
164+
printTop();
156165
}
157166

158-
/* storeVariable: stores the value of a variable (a to z) to the corresponding
159-
* memory location in mem */
160-
void storeVariable(double mem[], char variable)
167+
/* mathf: call the appropriate math function according to value of s */
168+
int mathfunction(char s[])
161169
{
162-
double value;
170+
double op2;
163171

164-
if (variable == 'P') { /* last printed value variable */
165-
value = lastPrint; /* fetch last printed value value */
166-
mem[MAXVAR] = value; /* last location is reserved for P */
167-
} else {
168-
pop(); /* pop stored value by fetchVariable */
169-
value = pop(); /* variable value - top of the stack */
170-
variable = tolower(variable);
171-
mem[variable - 'a'] = value;
172-
push(value);
173-
}
172+
if (strcmp(s, "sin") == 0)
173+
push(sin(pop()));
174+
else if (strcmp(s, "cos") == 0)
175+
push(cos(pop()));
176+
else if (strcmp(s, "exp") == 0)
177+
push(exp(pop()));
178+
else if (strcmp(s, "sqrt") == 0)
179+
push(sqrt(pop()));
180+
else if (strcmp(s, "pow") == 0) {
181+
op2 = pop();
182+
push(pow(pop(), op2));
183+
} else
184+
return 0;
185+
return 1;
186+
}
187+
188+
/* storeVariable: stores the value of a variable (a to z) to the corrosponding
189+
* memory location in mem */
190+
void storeVariable(void)
191+
{
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 */
174196
}
175197

176198
/* fetchVariable: fetches variable value from memory and pushes to the top of
177199
* the stack */
178-
void fetchVariable(double mem[], char variable)
200+
void fetchVariable(void)
179201
{
180-
if (variable == 'P') /* last printed value variable */
181-
push(mem[MAXVAR]); /* last location is reserved for P */
202+
if (variable == 'R')
203+
push(lastPrint);
182204
else {
183205
variable = tolower(variable);
184-
push(mem[variable - 'a']); /* push value to the top of the stack */
206+
push(mem[variable - 'a']);
185207
}
186208
}
187209

188210
/* clearMemory: initializes values of mem to 0 */
189-
void clearMemory(double mem[], int size)
211+
void clearMemory(void)
190212
{
191213
int i;
192214

193-
for (i = 0; i <= size; ++i)
215+
for (i = 0; i <= MAXVAR; ++i)
194216
mem[i] = 0;
217+
printf("memory cleared\n");
218+
stackcmd = 1; /* skip pop print */
195219
}
196220

197221
/* reverse Polish Calculator */
@@ -200,9 +224,8 @@ int main(void)
200224
int type;
201225
double op2;
202226
char s[MAXOP];
203-
static double mem[MAXVAR]; /* variables values */
204-
205-
while ((type = getop(s)) != END) {
227+
228+
while ((type = getop(s)) != EOF) {
206229
switch (type) {
207230
case NUMBER:
208231
push(atof(s));
@@ -243,33 +266,21 @@ int main(void)
243266
case '~':
244267
clearStack();
245268
break;
246-
case '$':
247-
storeVariable(mem, variable);
269+
case '=':
270+
storeVariable();
248271
break;
249272
case '\n':
250-
lastPrint = pop();
251-
printf("\t%.8g\n", lastPrint);
252-
storeVariable(mem, 'P'); /* store last printed value in P */
273+
if (!stackcmd)
274+
printf("\t%.8g\n", lastPrint = pop());
275+
stackcmd = 0;
253276
break;
254277
case MATH:
255278
if (strlen(s) == 1) {
256279
variable = s[0];
257-
fetchVariable(mem, variable);
258-
} else if (strcmp(s, "sin") == MATCH)
259-
push(sin(pop()));
260-
else if (strcmp(s, "cos") == MATCH)
261-
push(cos(pop()));
262-
else if (strcmp(s, "exp") == MATCH)
263-
push(exp(pop()));
264-
else if (strcmp(s, "sqrt") == MATCH)
265-
push(sqrt(pop()));
266-
else if (strcmp(s, "pow") == MATCH) {
267-
op2 = pop();
268-
push(pow(pop(), op2));
269-
} else if (strcmp(s, "mc") == MATCH) {
270-
clearMemory(mem, MAXVAR);
271-
printf("memory cleared\n");
272-
} else
280+
fetchVariable();
281+
} else if (strcmp(s, "mc") == 0)
282+
clearMemory();
283+
else if (!mathfunction(s))
273284
printf("error: unknown command %s\n", s);
274285
break;
275286
default:

0 commit comments

Comments
 (0)