K&R C Programs Exercise 4-4

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 accessval[sp-1] and val[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 require sp > 0; always check before accessing
  • Clear is O(1) — resetting sp = 0 is sufficient; the values in val[] 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

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>