Table of Contents
What Is an Enum in C?
An enum is a user-defined data type that assigns meaningful names to integer constants. Instead of using raw numbers, enums let you use named values separated by a comma.
Syntax of Enum in C
enum enum_name {
constant1,
constant2,
constant3
};
Declaring an Enum
1. Basic Enum Declaration: This is the standard way to define a set of named integer constants. The compiler by default assigns integer values starting from 0 to the members of the enum.
enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY
};MONDAY = 0, TUESDAY = 1, WEDNESDAY = 2, …

Here by default the compiler allocates numbers to the names starting from 0. Once declared, you use enum Day like a data type (just like int or float) to create variables.
Consider a code example below.
#include
// 1. Declaration
enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY
};
int main() {
// 2. Creating a variable
enum Day today;
// 3. Assigning a value
today = WEDNESDAY;
// 4. Printing (Prints the integer value)
// Output: 2
printf("Day Index: %d", today);
return 0;
}
// Day Index: 2
This code defines a custom enum for weekdays, assigns WEDNESDAY to a variable, and prints the integer 2 to demonstrate that enums internally store named constants as numbers starting from zero.
2. Immediate Variable Declaration
In this method we define the enum and create a variable in the same statement. This keeps the code concise. The keyword enum is used to define the type, while the variable is required to allocate actual memory.
enum enum_name {
constant1,
constant2,
constant3,
...
} variable_name;Consider the code below for the immediate Variable Declaration
#include
// Define Type + Create Variable 'myColor'
enum Color {
RED,
GREEN,
BLUE
} myColor;
int main() {
myColor = RED; // Assign value
if (myColor == RED) {
printf("The color is Red (Value: %d)", myColor);
}
return 0;
}
// The color is Red (Value: 0)
Enum in Switch Statements (Very Common Use)
The most common use of enum is its use in the switch cases. Using Enums in switch cases replaces confusing numbers (like case 0, case 1) with readable English names (like case RED, case GREEN), making your code self-documenting and easier to maintain.
#include
enum GameState {
MENU,
PLAYING,
GAME_OVER
};
int main() {
enum GameState state = PLAYING;
// 2. Switch on the Enum variable
switch(state) {
case MENU:
printf("Displaying Main Menu...\n");
break;
case PLAYING:
printf("Game Started! Player is moving.\n");
break;
case GAME_OVER:
printf("You died. Try again?\n");
break;
default:
printf("Unknown State error.\n");
}
return 0;
}
// Game Started! Player is moving.
This code defines an enumeration for game states, sets the current state to PLAYING and uses a switch statement to match that value and print the corresponding gameplay message.
Enum with Union (Advanced & Powerful)
Enums are often used with unions to track active data. A raw Union is dangerous because you don’t know which member holds valid data. By pairing it with an Enum, you create a Tag that tracks exactly what type of data is currently stored in the union.
#include
enum DataType {
INT,
FLOAT
};
// 2. Define Union
union Data {
int i;
float f;
};
// 3. Define the Container (Struct)
struct Value {
enum DataType type;
union Data data;
};
// Helper function to safely print the value
void printValue(struct Value v) {
if (v.type == INT) {
printf("Type: Integer | Value: %d\n", v.data.i);
}
else if (v.type == FLOAT) {
printf("Type: Float | Value: %.2f\n", v.data.f);
}
}
int main() {
struct Value v1, v2;
// SCENARIO 1: Storing an Integer
v1.type = INT;
v1.data.i = 1024;
printValue(v1);
// SCENARIO 2: Storing a Float
v2.type = FLOAT;
v2.data.f = 98.6;
printValue(v2);
return 0;
}
// Type: Integer | Value: 1024
// Type: Float | Value: 98.60
Step-by-Step Explanation
1. The Tag (enum DataType):
- This acts as a label. INT (0) means “I am holding an integer,” and FLOAT (1) means “I am holding a float.”
2. The Payload (union Data):
- This is the shared memory box. It can hold i OR f, but not both at the same time.
3. The Wrapper (struct Value):
- This bundles the Tag and the Payload together so they never get separated.
4. The Logic (printValue):
- This is the safety mechanism. Before reading the Union, it checks v.type.
- If type == INT, it safely reads v.data.i.
- If type == FLOAT, it safely reads v.data.f.
Why do this?
Without the enum tag, if you stored a Float but tried to print it as an Integer, you would get garbage values. The tag ensures you always read the data correctly.
Applications
- State Representation: Enums are used to represent distinct states in a program, such as IDLE, RUNNING or STOPPED, making state transitions easier to manage and understand.
- Menu-Driven Programs: Enums assign meaningful names to menu options, reducing the use of hard-coded numbers and improving program readability.
- Error Handling and Status Codes: Enums define standardized error and status codes, ensuring consistent interpretation of program outcomes across modules.
- Embedded Systems and Hardware Control: Enums represent operating modes, commands and control signals in embedded systems, simplifying device-level programming.
- Compilers and Interpreters: Enums classify tokens, syntax elements and operation types, helping compilers efficiently process source code.
Frequently Asked Questions (FAQs)
1) What is an enum in C?
An enum in C is a user-defined data type that assigns names to integer constants to improve code readability.
2) Are enum values stored as integers?
Yes, enum values are stored internally as integers.
3) Can we assign custom values to enum constants?
Yes, enum constants can be assigned explicit integer values during declaration.
4) Can enum values be changed at runtime?
No, enum constants are fixed at compile time and cannot be modified.