Back to C Programming
2026-02-208 min read

enum definition (C Programming)

Learn enum definition (C Programming) step by step with clear examples and exercises.

Why This Matters

Enums in C programming play a crucial role by providing a means to define custom data types with predefined sets of named values. They help make your code more readable, maintainable, and easier to understand by giving meaningful names to integer constants. Enums are essential when working with complex data structures or enforcing specific rules in your program.

Prerequisites

Before diving into enums, it's crucial to have a solid understanding of the following C programming concepts:

  1. Basic syntax and data types (int, char, etc.)
  2. Variables and constants
  3. Control structures (if-else, loops)
  4. Functions and function prototypes
  5. Pointers and arrays
  6. Structures and unions
  7. Preprocessor directives (#include, #define)
  8. File input/output (stdio.h)
  9. Understanding the difference between enumeration constants, regular integer constants, and variables.
  10. Basic arithmetic operations and data type conversions.

Core Concept

Definition

An enumerated type is a user-defined data type composed of a set of named integer constants. You can declare an enumeration using the enum keyword, followed by a sequence of identifiers separated by commas. By default, each enumerator (identifier) has an integer value that increases by 1 from zero for the first enumerator.

enum color { RED, GREEN, BLUE };

In this example, we define a new data type called color, which consists of three enumerators: RED, GREEN, and BLUE. Each enumerator has an integer value associated with it: 0 for RED, 1 for GREEN, and 2 for BLUE.

Fixed Underlying Type

Starting from C99, you can also specify the underlying type of an enumeration by appending a colon (:) followed by the desired type (e.g., int, unsigned int, etc.) after the enum name. This allows for more control over the size and range of the enumerators' integer values.

enum myEnum : unsigned short { ONE = 1, TWO = 2, THREE = 3 };

In this case, we define an enumerated type called myEnum, with the underlying type set to unsigned short. The enumerators now have values of 1, 2, and 3, respectively.

Initializing Enumerator Values

You can also explicitly initialize the value of an enumerator by assigning a constant expression (an integer literal or another enumerator) to it, using the equals sign (=). The initializer sets the value of the enumerator and determines the values of subsequent enumerators.

enum days { SUNDAY = 0, MONDAY = 1, TUESDAY = 2, WEDNESDAY = 3, THURSDAY = 4, FRIDAY = 5, SATURDAY = 6 };

In this example, we define an enumerated type called days, with the initial value of SUNDAY set to 0. The remaining enumerators are assigned values incrementally, starting from 1.

Enumeration Constants as Operands

Enumeration constants can be used in expressions and assignments just like regular integer constants. However, Note that that the type of an enumeration constant is the underlying type specified during its declaration (or int if no underlying type is specified).

enum color c = RED;
int i = GREEN;
unsigned int ui = BLUE;

In this example, we declare a variable of enumerated type color, assign the value RED, and initialize an integer variable with the value of GREEN. We also cast BLUE to an unsigned int for assignment.

Using Enumeration Constants in Arithmetic Expressions

When using enumeration constants in arithmetic expressions, it's important to ensure that the underlying types are compatible. Otherwise, type promotions may occur, leading to unexpected behavior or compiler warnings. To avoid this issue, you can explicitly cast the operands to a common type before performing the operation.

enum days { SUNDAY = 0, MONDAY = 1 };
enum months { JANUARY = 0, FEBRUARY = 1 };

int main() {
enum days day = SUNDAY;
enum months month = JANUARY;

// Incorrect: different underlying types in expression
if (day + month == SUNDAY + JANUARY) {
printf("Sunday is the same as January?\n"); // Output: unexpected result
}

// Correct: casting operands to a common type before comparison
if ((int)day + (int)month == (int)SUNDAY + (int)JANUARY) {
printf("Sunday and January are equal.\n");
}

return 0;
}

Worked Example

Let's create a simple program that demonstrates the use of enums in C:

#include <stdio.h>

// Define an enumerated type for colors
enum color { RED, GREEN, BLUE };

int main() {
// Declare variables of the enum type and regular integer types
enum color c1 = RED;
int i1 = 0;
unsigned int ui1 = 4294967295U;

printf("c1: %d\n", (int)c1); // Cast to int for printing
printf("i1: %d\n", i1);
printf("ui1: %u\n", ui1);

// Assign values from different data types to the enum variable
c1 = GREEN;
i1 = BLUE;
ui1 = (unsigned int)RED;

printf("\nc1: %d\n", (int)c1);
printf("i1: %d\n", i1);
printf("ui1: %u\n", ui1);

// Perform arithmetic operations with enumeration constants
enum color c2 = RED + 2; // Move two positions forward from RED
int i2 = (int)RED + (int)BLUE; // Add the values of RED and BLUE
printf("\nc2: %d\n", (int)c2);
printf("i2: %d\n", i2);

return 0;
}

When you run this program, it will output the following:

c1: 0
i1: 0
ui1: 4294967295

c1: 1
i1: 2
ui1: 0

c2: 2
i2: 5

Common Mistakes

Forgetting the Semicolon

Remember to end each enum declaration and enumerator with a semicolon. Failing to do so will result in a syntax error.

// Incorrect: missing semicolons
enum color { RED, GREEN, BLUE } c; // Syntax error

Misunderstanding Enumerator Values

Be aware that enumerators don't necessarily have the values you might expect. The initial value of an enumerator is determined by its position in the enum declaration and can be influenced by explicit initialization or the underlying type.

// Incorrect: expecting enumerators to have specific values
enum days { SUNDAY = 0, MONDAY = 1, TUESDAY = 2, WEDNESDAY = 3 };
int main() {
printf("SUNDAY: %d\n", SUNDAY); // Output: 0
printf("MONDAY: %d\n", MONDAY); // Output: 1
printf("TUESDAY: %d\n", TUESDAY); // Output: 2
printf("WEDNESDAY: %d\n", WEDNESDAY); // Output: 3

// Correct: using enumerators as constants
enum days day = SUNDAY;
printf("day: %d\n", day); // Output: 0
}

Using Enumeration Constants with Different Underlying Types in Expressions

When using enumeration constants in expressions, it's important to ensure that the underlying types are compatible. Otherwise, type promotions may occur, leading to unexpected behavior or compiler warnings. To avoid this issue, you can explicitly cast the operands to a common type before performing the operation.

// Incorrect: different underlying types in expression
enum days { SUNDAY = 0, MONDAY = 1 };
enum months { JANUARY = 0, FEBRUARY = 1 };

int main() {
enum days day = SUNDAY;
enum months month = JANUARY;

// Incorrect: different underlying types in expression
if (day + month == SUNDAY + JANUARY) {
printf("Sunday is the same as January?\n"); // Output: unexpected result
}

// Correct: casting operands to a common type before comparison
if ((int)day + (int)month == (int)SUNDAY + (int)JANUARY) {
printf("Sunday and January are equal.\n");
}

return 0;
}

Practice Questions

  1. Write a program that defines an enumerated type for the suits in a deck of cards (SPADES, HEARTS, DIAMONDS, CLUBS) and another enumerated type for card ranks (ACE, TWO, THREE, ..., KING). Create a structure called Card with members for suit, rank, and value (ace high). Write a function that calculates the total value of a hand of five cards.
  2. Modify the previous program to handle jokers, which can be either wild or take the value of the last card played. Add two new enumerators for JOKER_WILD and JOKER_TAKE_LAST.
  3. Write a function that takes an array of integers as input and returns the maximum number of unique enum values it contains (assuming you have defined an appropriate enumerated type).
  4. Implement a simple command-line interface for managing to-do lists using enums for task statuses (PENDING, IN_PROGRESS, COMPLETED) and priorities (LOW, MEDIUM, HIGH). Allow users to add, list, complete, and delete tasks based on their status and priority.
  5. Write a program that defines an enumerated type for traffic signals (RED, YELLOW, GREEN), creates a function to simulate the sequence of traffic signals, and another function to handle user input for crossing the road safely.
  6. Create a program that uses enums to represent different shapes (POINT, LINE, RECTANGLE, CIRCLE) and their areas. Write functions to calculate the area of each shape and display the results.
  7. Implement a simple text-based game using enums for game states (GAME_START, GAME_OVER, GAME_WIN), player actions (MOVE_UP, MOVE_DOWN, MOVE_LEFT, MOVE_RIGHT), and obstacles (WALL, MONSTER).

FAQ

Why should I use enums instead of regular integer constants?

Using enums makes your code more readable and maintainable by giving meaningful names to integer constants. This improves the overall structure and organization of your program, making it easier for other developers (or yourself) to understand and modify in the future.

Can I use enumeration constants in arithmetic expressions?

Yes, you can use enumeration constants in arithmetic expressions just like regular integer constants. However, Note that that the type of an enumeration constant is the underlying type specified during its declaration (or int if no underlying type is specified).

Can I define nested enumerations?

No, C does not support nesting enumerations directly. You can create a new enumerated type within another enumerated type's scope, but the inner enumeration will not be considered a member of the outer one.

How do I compare enumerators for equality or inequality?

You can compare enumerators using regular comparison operators (==, !=, etc.). However, keep in mind that comparing enumerators with different underlying types may result in unexpected behavior due to potential type promotions. To avoid this issue, you should explicitly cast the operands to a common type before performing the comparison.

enum days { SUNDAY = 0, MONDAY = 1 };
enum months { JANUARY = 0, FEBRUARY = 1 };

int main() {
enum days day = SUNDAY;
enum months month = JANUARY;

// Incorrect: different underlying types in comparison
if (day == month) {
printf("Sunday is the same as January?\n"); // Output: unexpected result
}

// Correct: casting operands to a common type before comparison
if ((int)day == (int)month) {
printf("Sunday and January are equal.\n");
}

return 0;
}