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 Lightis a new type, likestruct Pointwas.RED,YELLOW,GREENare its enumerators — named constants.- C numbers them for you, starting at 0:
REDis 0,YELLOWis 1,GREENis 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:
#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=2Run 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:
#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 500Run 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:
#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
redRun 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?