5.1.25 · D4C Programming

Exercises — Enumerations

1,904 words9 min readBack to topic

The single rule that powers almost every problem below:

Figure — Enumerations

L1 — Recognition

Exercise 1

State the integer value of every enumerator:

enum Dir { NORTH, EAST, SOUTH, WEST };
Recall Solution

No enumerator has an explicit value, so we start at 0 and add 1 each step (the recurrence with ).

  • NORTH = 0 (first, no init → 0)
  • EAST = 0 + 1 = 1
  • SOUTH = 1 + 1 = 2
  • WEST = 2 + 1 = 3

Exercise 2

True or false, and why: in enum Color { RED, GREEN, BLUE }; the statement printf("%d", GREEN); prints the text GREEN.

Recall Solution

False. C stores an enumerator as a plain int. There is no name table at runtime — the identifier GREEN was a compile-time label that the compiler already replaced with the number 1. So %d prints 1. To print the word you would need your own array const char* names[] = {"RED","GREEN","BLUE"}; and print names[GREEN].


L2 — Application

Exercise 3

Give the value of each enumerator:

enum E { A = 4, B, C, D = 10, E2, F };
Recall Solution

Apply "explicit overwrites, then +1 continues":

  • A = 4 (explicit)
  • B = 4 + 1 = 5
  • C = 5 + 1 = 6
  • D = 10 (explicit — restarts the count)
  • E2 = 10 + 1 = 11
  • F = 11 + 1 = 12

Exercise 4

What does this print, and why?

enum Http { OK = 200, CREATED, ACCEPTED, MOVED = 301, FOUND };
printf("%d %d\n", ACCEPTED, FOUND);
Recall Solution
  • OK = 200 (explicit)
  • CREATED = 201, ACCEPTED = 202
  • MOVED = 301 (explicit restart)
  • FOUND = 302

Output: 202 302.

Exercise 5

Fill the blanks so that LOW, MID, HIGH equal 10, 20, 30:

enum Level { LOW = ___, MID = ___, HIGH = ___ };
Recall Solution

Here the +1 rule cannot give jumps of 10, so we must set all three explicitly:

enum Level { LOW = 10, MID = 20, HIGH = 30 };

(You could write LOW = 10, MID = LOW + 10, HIGH = MID + 10 — arithmetic on constants is allowed since each is a compile-time integer.)


L3 — Analysis

Exercise 6

Are these two declarations legal in the same file? Explain.

enum A { CAT, DOG };
enum B { DOG, FISH };
Recall Solution

Illegal. Enumerators are not scoped inside their enum — they are plain identifiers dumped into the surrounding scope (unlike a struct field, which needs s.field). Both enum A and enum B try to define the identifier DOG in the same scope, which is a redefinition error. Only names must be unique; the enum they belong to does not create a namespace.

Exercise 7

Is this legal? What are the values?

enum Sig { WARN = 5, ERR, FATAL = 5 };
Recall Solution

Legal. Distinct names may share the same integer value.

  • WARN = 5 (explicit)
  • ERR = 5 + 1 = 6
  • FATAL = 5 (explicit — duplicate value of WARN, but a different name)

A switch (s) with case WARN: and case FATAL: would be a compile error, though — both labels equal 5, and switch statement forbids two case labels with the same value.

Exercise 8

enum Color { RED, GREEN, BLUE }; enum Color c = 99; — does this compile? What is stored?

Recall Solution

It compiles. In C an enum is freely convertible to/from int, so assigning 99 is allowed even though 99 names no color. c now holds the integer 99. C gives essentially no type safety here — treat an enum as a documented int. (A switch on c would simply match none of RED/GREEN/BLUE and fall through to default.)


L4 — Synthesis

Exercise 9

Use the "trailing COUNT" trick to declare an array with exactly one slot per weekday, without hard-coding 7. Show the enum and the array line.

Recall Solution

Put a sentinel last so it auto-equals the number of items before it (0..6 → count 7):

enum { MON, TUE, WED, THU, FRI, SAT, SUN, DAY_COUNT };
int hours[DAY_COUNT];   // DAY_COUNT == 7

MON=0 … SUN=6, so DAY_COUNT = 6 + 1 = ==7==. Add a new day before the sentinel and DAY_COUNT updates for free — the array resizes without you touching the number. See Arrays in C.

Exercise 10

Combine an enum with a name table so that printf can show the word. Write a const char* array and the print line for enum Color { RED, GREEN, BLUE }, then state what printf("%s\n", names[GREEN]); prints.

Recall Solution
enum Color { RED, GREEN, BLUE };
const char* names[] = { "RED", "GREEN", "BLUE" };
printf("%s\n", names[GREEN]);   // GREEN

Why it works: GREEN is the integer 1, so names[GREEN] is names[1], which is the string "GREEN". The array is the name lookup C never had — you provide it by hand. Output: GREEN. (This is safe only while every enumerator is a valid index 0..2, another reason the default 0-based numbering is so convenient.)


L5 — Mastery

Exercise 11

Design a state machine for a turnstile with states LOCKED, UNLOCKED and events PUSH, COIN. Using two enums and a switch, write the transition rule: a COIN unlocks; a PUSH on an unlocked turnstile locks it again. Then trace the state starting from LOCKED after the event sequence PUSH, COIN, PUSH, PUSH.

Recall Solution
enum State { LOCKED, UNLOCKED };      // 0, 1
enum Event { PUSH, COIN };            // 0, 1
 
enum State next(enum State s, enum Event e) {
    switch (s) {
        case LOCKED:
            return (e == COIN) ? UNLOCKED : LOCKED;
        case UNLOCKED:
            return (e == PUSH) ? LOCKED : UNLOCKED;
    }
    return s;  // unreachable, silences warnings
}

Trace from LOCKED:

  1. PUSH on LOCKED → not a COIN → stays LOCKED
  2. COIN on LOCKEDCOINUNLOCKED
  3. PUSH on UNLOCKEDPUSHLOCKED
  4. PUSH on LOCKED → not a COIN → stays LOCKED

Final state: LOCKED (integer value 0). Enums make each case read like English — the classic payoff of pairing enums with switch statement.

Figure — Enumerations

Exercise 12

Use typedef to make Color usable without the enum keyword, then declare a variable and assign BLUE. What integer does it hold?

Recall Solution
typedef enum { RED, GREEN, BLUE } Color;
Color c = BLUE;
printf("%d\n", c);   // 2

typedef gives the anonymous enum the alias Color, so you write Color c instead of enum Color c. Since RED=0, GREEN=1, BLUE=2, the variable holds the integer 2. Output: 2.


Active recall

Recall Rapid re-test (open after attempting)

Value of WEST in {NORTH,EAST,SOUTH,WEST}? ::: 3 enum E { A=4, B, C, D=10, E2, F }; value of F? ::: 12 Value of FOUND in {OK=200,CREATED,ACCEPTED,MOVED=301,FOUND}? ::: 302 Can WARN=5 and FATAL=5 coexist? ::: Yes — names differ, values may repeat DAY_COUNT in {MON..SUN, DAY_COUNT}? ::: 7 Turnstile final state after PUSH,COIN,PUSH,PUSH from LOCKED? ::: LOCKED (0) Value held by Color c = BLUE;? ::: 2

Connections

  • Parent: Enumerations in C
  • Integer Types in C — why every enumerator is really an int.
  • switch statement — Exercises 7, 11.
  • Arrays in C — the COUNT sizing trick (Ex. 9, 10).
  • struct in C — contrast: struct fields are scoped, enumerators are not (Ex. 6).
  • typedef — Exercise 12.