Exercise 4-4. Add commands to print the top element of the stack without popping it, to duplicate it, and to swap the top two elements. Add a command to clear the stack.
Four new commands, each operating directly on the stack array. None requires new data structures — just index arithmetic on val[] and sp. These are classic stack primitives found in languages like Forth and PostScript. The natural command characters: p (peek), d (duplicate), s (swap), c (clear).
Stack Operations to Add
/* K&R Exercise 4-4 — RPN calculator: peek, dup, swap, clear
* Add these cases to the main switch in the calculator from Ex 4-3. */
/* peek — print top without popping */
case 'p':
if (sp > 0)
printf("\t%.8g\n", val[sp-1]);
else
printf("error: stack empty\n");
break;
/* dup — duplicate top */
case 'd':
if (sp > 0)
push(val[sp-1]);
else
printf("error: stack empty\n");
break;
/* swap — exchange top two */
case 's': {
double tmp;
if (sp >= 2) {
tmp = val[sp-1];
val[sp-1] = val[sp-2];
val[sp-2] = tmp;
} else {
printf("error: need 2 elements to swap\n");
}
break;
}
/* clear — empty the stack */
case 'c':
sp = 0;
break;
Complete Minimal Demo
/* Standalone test — builds on the calculator structure from Ex 4-3 */
#include <stdio.h>
#define MAXVAL 100
static double val[MAXVAL];
static int sp = 0;
void push(double f) { if (sp < MAXVAL) val[sp++] = f; }
double pop(void) { return sp > 0 ? val[--sp] : 0.0; }
void show_stack(const char *label) {
int i;
printf("%s: [", label);
for (i = 0; i < sp; i++) printf(" %.4g", val[i]);
printf(" ] (top = %d)\n", sp-1);
}
int main(void)
{
push(10.0); push(20.0); push(30.0);
show_stack("initial"); /* [10 20 30] */
/* peek */
printf("peek: %.4g\n", val[sp-1]);
show_stack("after peek"); /* unchanged */
/* dup */
push(val[sp-1]);
show_stack("after dup"); /* [10 20 30 30] */
/* swap */
{ double t = val[sp-1]; val[sp-1] = val[sp-2]; val[sp-2] = t; }
show_stack("after swap"); /* [10 20 30 30] — same (top two were equal) */
push(99.0);
show_stack("pushed 99");
{ double t = val[sp-1]; val[sp-1] = val[sp-2]; val[sp-2] = t; }
show_stack("after swap"); /* [10 20 30 99 30] swapped */
/* clear */
sp = 0;
show_stack("after clear"); /* [] */
return 0;
}
Compile and Run
gcc -ansi -Wall ex4-4.c -o ex4-4
./ex4-4
Sample Output
initial: [ 10 20 30 ] (top = 2) peek: 30 after peek: [ 10 20 30 ] (top = 2) after dup: [ 10 20 30 30 ] (top = 3) after swap: [ 10 20 30 30 ] (top = 3) pushed 99: [ 10 20 30 30 99 ] (top = 4) after swap: [ 10 20 30 99 30 ] (top = 4) after clear: [ ] (top = -1)
What This Exercise Teaches
- Stack primitives — peek, dup, swap, and clear are the standard stack manipulation words in stack-based languages (Forth, PostScript, JVM bytecode)
- Direct index access —
val[sp-1]andval[sp-2]peek without popping; this is valid because the stack is an array, not an opaque ADT - Guard conditions — swap requires
sp >= 2; peek/dup requiresp > 0; always check before accessing - Clear is O(1) — resetting
sp = 0is sufficient; the values inval[]are never accessed again
Set Up Your C Environment
← Exercise 4-3 |
Chapter 4 Solutions |
Exercise 4-5 →
Book: The C Programming Language, 2nd Ed — Kernighan & Ritchie