Skip to content
FollowtheDamnCode

Enums

Names for a fixed set of choices.

5 minute read

Big idea

An enum gives names to a small set of related whole numbers — RED, YELLOW, GREEN instead of 0, 1, 2 — so your code says what it means.

The idea

A traffic light has three states. You could store them as plain numbers and remember that 0 means red. Or you can name them:

enum Light { RED, YELLOW, GREEN };
  • enum Light is a new type, like struct Point was.
  • RED, YELLOW, GREEN are its enumerators — named constants.
  • C numbers them for you, starting at 0: RED is 0, YELLOW is 1, GREEN is 2.

Now a variable can hold one of them:

enum Light now = RED;
if (now == RED) {
    printf("Stop\n");
}

Under the hood an enum value is just an int, so printf prints it with %d:

Enumerators are numbered from 0
#include <stdio.h>

enum Light { RED, YELLOW, GREEN };

int main(void) {
    printf("RED=%d YELLOW=%d GREEN=%d\n", RED, YELLOW, GREEN);
    enum Light now = GREEN;
    printf("now=%d\n", now);
    return 0;
}
output
RED=0 YELLOW=1 GREEN=2
now=2

Run and edit it in the app.

Choosing the numbers yourself

Give an enumerator a value with =. The ones after it keep counting up from there:

Predict: what numbers do these get?
#include <stdio.h>

enum Month { JAN = 1, FEB, MAR, APR };
enum Status { OK = 0, NOT_FOUND = 404, SERVER_ERROR = 500 };

int main(void) {
    printf("%d %d %d\n", JAN, FEB, APR);
    printf("%d %d\n", NOT_FOUND, SERVER_ERROR);
    return 0;
}
What does it print? Show the answer
1 2 4
404 500

Run and edit it in the app.

JAN = 1 starts the count at 1, so FEB is 2 and APR is 4.

Enums and switch

Enums and switch belong together — one case per named state:

A traffic light that steps through its states
#include <stdio.h>

typedef enum { RED, YELLOW, GREEN } Light;

const char *light_name(Light l) {
    switch (l) {
        case RED:    return "red";
        case YELLOW: return "yellow";
        case GREEN:  return "green";
    }
    return "?";
}

Light next(Light l) {
    switch (l) {
        case RED:    return GREEN;
        case GREEN:  return YELLOW;
        case YELLOW: return RED;
    }
    return RED;
}

int main(void) {
    Light l = RED;
    for (int i = 0; i < 4; i++) {
        printf("%s\n", light_name(l));
        l = next(l);
    }
    return 0;
}
output
red
green
yellow
red

Run and edit it in the app.

typedef enum { … } Light; works just like it did for structs — now the type is simply Light.

Watch it

A handy trick: counting the members

Put one extra name at the end, and it equals the number of real members — perfect for sizing an array that has one slot per state:

enum Color { C_RED, C_GREEN, C_BLUE, COLOR_COUNT };   // COLOR_COUNT is 3
int votes[COLOR_COUNT] = {0};

Given enum Size { SMALL = 10, MEDIUM, LARGE = 50, HUGE }; what is HUGE?

Common mistake

Thinking the names are text. printf("%s", RED) doesn't print RED — RED is the number 0. To print a name, write a function like light_name above that maps each value to a string.

And C won't stop you putting any int into an enum variable (Light l = 7; compiles). Enums make code clearer; they don't check your values.

Think of it like

Seat numbers vs. seat names. The theatre still uses numbers internally, but the ticket says "Balcony, Row A" — easier to read and much harder to get wrong.

Key terms

  • Enum (enum) — A type whose values are a set of named integer constants.
  • Enumerator — One of those names, like RED.
  • Underlying value — The integer an enumerator stands for; counting starts at 0 unless you say otherwise.

Check yourself

In enum Light { RED, YELLOW, GREEN }; what is the value of GREEN?

What does printf("%d", YELLOW); print for that enum?

Which statement pairs most naturally with an enum?