When a data type has only a few possible values, each with its own specific meaning, defining these values as an enum (short for “enumeration”) can enhance code readability.

1
2
3
4
5
enum colors { RED, GREEN, BLUE };

printf("%d\n", RED); // 0
printf("%d\n", GREEN); // 1
printf("%d\n", BLUE); // 2

In the example above, if a program requires three colors, we can use the enum command to define these colors as a single enumeration type called colors, which consists of the possible values RED, GREEN, and BLUE. These names automatically become integer constants, with the compiler assigning them the values 0, 1, and 2, respectively. This makes RED much more readable than just using the number 0.

Note that the names of constants in an enum follow the identifier naming conventions, but they are typically written in uppercase.

You can declare a variable as an enum type as follows:

1
enum colors color;

This code declares the variable color as an enum colors type, allowing it to take on one of the constant values RED, GREEN, or BLUE.

1
2
color = BLUE;
printf("%i\n", color); // 2

Here, we assign the value BLUE to the variable color, which corresponds to the constant with a value of 2.

The typedef command can be used to create an alias for an enum type:

1
2
3
4
5
6
7
8
9
typedef enum {
SHEEP,
WHEAT,
WOOD,
BRICK,
ORE
} RESOURCE;

RESOURCE r;

In this example, RESOURCE serves as an alias for the enum type. You can use this alias when declaring variables.

Another less common syntax allows you to declare an enum type and assign values to variables in the same line:

1
2
3
4
5
6
7
enum {
SHEEP,
WHEAT,
WOOD,
BRICK,
ORE
} r = BRICK, s = WOOD;

In this case, r is assigned the value 3 (BRICK), and s is assigned the value 2 (WOOD).

Since the enum automatically declares constants, sometimes the purpose of using an enum is simply to define a set of constants. This can be done succinctly:

1
2
3
enum { ONE, TWO };

printf("%d %d", ONE, TWO); // 0 1

In this example, enum is a keyword followed by a block of code, within which the constants are declared. ONE and TWO are two enum constants.

Constants are separated by commas, and the trailing comma after the last constant is optional.

1
enum { ONE, TWO, };

Because enum automatically assigns increasing values starting from 0, you do not need to assign values manually. However, C does allow you to specify values for enum constants, but only as integers, not other types. Therefore, any situation where you can use integers, you can also use enum constants.

1
2
3
enum { ONE = 1, TWO = 2 };

printf("%d %d", ONE, TWO); // 1 2

enum constants can have non-contiguous values:

1
enum { X = 2, Y = 18, Z = -2 };

They can also share the same value:

1
enum { X = 2, Y = 2, Z = 2 };

If some constants in a set are assigned values while others are not, the unspecified constants will automatically increment from the last specified value.

1
2
3
4
5
6
7
8
9
10
enum {
A, // 0
B, // 1
C = 4, // 4
D, // 5
E, // 6
F = 3, // 3
G, // 4
H // 5
};

The scope of an enum is the same as that of a variable. If declared at the top level, it is valid throughout the file; if declared within a block, it is only valid in that block. Compared to using int for constants, the advantage of enum is that it clearly conveys the intent of the code.