Enumerations in C
Create named constants for better code readability. Instead of using 0, 1, 2 for days, use MON, TUE, WED with enums.
Track Your Progress
Sign in to save your learning progress
What You Will Learn
- ✓Declare enumerations
- ✓Set custom enum values
- ✓Use enums with switch statements
- ✓Make code more readable with enums
01What is an Enumeration?
An enumeration (enum) is a user-defined type that consists of a set of named integer constants. It makes your code more readable by giving meaningful names to numeric values.
Why Use Enums?
Without Enums (Magic Numbers)
int status = 0; // What does 0 mean?if (status == 1) { /* success? error? */ }if (status == 2) { /* pending? */ }Hard to understand and maintain
✓ With Enums (Named Constants)
enum Status status = SUCCESS;if (status == ERROR) { /* clear! */ }if (status == PENDING) { /* obvious! */ }Self-documenting code
Common Use Cases
- • Days of the week (MONDAY, TUESDAY, ...)
- • Status codes (SUCCESS, ERROR, PENDING)
- • Directions (NORTH, SOUTH, EAST, WEST)
- • Colors (RED, GREEN, BLUE)
- • Menu options, game states, modes...
What Are Enums Really?
Under the hood, enums are just integers with names. When you write:
What You Write:
What Compiler Sees:
Why is this useful?
- • Type safety: Compiler can warn if you use wrong enum type
- • IDE support: Auto-complete shows all valid options
- • Self-documenting:
if (status == ERROR)is clearer thanif (status == 1) - • Maintainable: Add new values without changing existing code
02Declaring Enumerations
1#include <stdio.h>23// Define an enumeration4enum Day {5 SUNDAY, // = 0 (default, starts at 0)6 MONDAY, // = 17 TUESDAY, // = 28 WEDNESDAY, // = 39 THURSDAY, // = 410 FRIDAY, // = 511 SATURDAY // = 612};1314int main() {15 // Declare an enum variable16 enum Day today = WEDNESDAY;17 enum Day tomorrow = THURSDAY;18 19 printf("Today is day number: %d\n", today); // 320 printf("Tomorrow is day number: %d\n", tomorrow); // 421 22 // Can use in conditions23 if (today == WEDNESDAY) {24 printf("It's Wednesday!\n");25 }26 27 // Enums are integers - can do arithmetic (not recommended)28 enum Day nextDay = today + 1;29 printf("Next day number: %d\n", nextDay); // 430 31 return 0;32}Output:
Tomorrow is day number: 4
It's Wednesday!
Next day number: 4
How This Program Works
enum Day {...} — Defines 7 named constants. SUNDAY=0, MONDAY=1, ..., SATURDAY=6 (auto-increments from 0).
enum Day today = WEDNESDAY — Creates variable and assigns WEDNESDAY (which equals 3).
printf("%d", today) — Prints 3, because internally WEDNESDAY is stored as the integer 3.
today == WEDNESDAY — Compares integers: 3 == 3 is true! Much more readable than today == 3.
today + 1 — Since enums are integers, arithmetic works: 3 + 1 = 4 (THURSDAY).
Default Values
By default, the first enum constant is 0, and each subsequent constant is previous + 1.
03Custom Enum Values
You can assign specific integer values to enum constants:
1#include <stdio.h>23// Custom starting value4enum Month {5 JANUARY = 1, // Start at 1 instead of 06 FEBRUARY, // = 2 (auto-increments)7 MARCH, // = 38 APRIL, // = 49 // ... etc10 DECEMBER = 1211};1213// Arbitrary values (like bit flags)14enum Permission {15 READ = 1, // 0001 in binary16 WRITE = 2, // 001017 EXECUTE = 4, // 010018 DELETE = 8 // 100019};2021// HTTP status codes22enum HttpStatus {23 OK = 200,24 CREATED = 201,25 BAD_REQUEST = 400,26 UNAUTHORIZED = 401,27 NOT_FOUND = 404,28 SERVER_ERROR = 50029};3031int main() {32 enum Month currentMonth = MARCH;33 printf("Month number: %d\n", currentMonth); // 334 35 // Combine permissions with bitwise OR36 int userPerms = READ | WRITE; // 3 (0011)37 printf("User permissions: %d\n", userPerms);38 39 // Check permission with bitwise AND40 if (userPerms & WRITE) {41 printf("User can write!\n");42 }43 44 enum HttpStatus response = NOT_FOUND;45 printf("HTTP Status: %d\n", response); // 40446 47 return 0;48}Enum Value Rules
- • First constant defaults to
0if not specified - • Each subsequent constant is
previous + 1 - • You can assign any integer value
- • Multiple constants can have the same value (aliases)
- • Values can be negative
1// Same values (aliases)2enum Boolean {3 FALSE = 0,4 TRUE = 1,5 NO = 0, // Same as FALSE6 YES = 1 // Same as TRUE7};89// Negative values10enum Temperature {11 FREEZING = -10,12 COLD = 0,13 WARM = 20,14 HOT = 3515};04Enums with switch Statements
Enums work perfectly with switch statements, making your code clean and readable:
1#include <stdio.h>23enum TrafficLight {4 RED,5 YELLOW,6 GREEN7};89const char* getAction(enum TrafficLight light) {10 switch (light) {11 case RED:12 return "STOP!";13 case YELLOW:14 return "SLOW DOWN";15 case GREEN:16 return "GO";17 default:18 return "UNKNOWN";19 }20}2122int main() {23 enum TrafficLight current = RED;24 25 printf("Light is RED: %s\n", getAction(RED));26 printf("Light is YELLOW: %s\n", getAction(YELLOW));27 printf("Light is GREEN: %s\n", getAction(GREEN));28 29 // Simulate light change30 for (int i = 0; i < 6; i++) {31 printf("\nCycle %d: ", i + 1);32 current = i % 3; // Cycles through 0, 1, 233 printf("%s", getAction(current));34 }35 printf("\n");36 37 return 0;38}Output:
Light is YELLOW: SLOW DOWN
Light is GREEN: GO
Cycle 1: STOP!
Cycle 2: SLOW DOWN
Cycle 3: GO
Cycle 4: STOP!
Cycle 5: SLOW DOWN
Cycle 6: GO
05typedef with Enums
Use typedef to create shorter type names (avoid writing enum every time):
Without typedef
enum Status { OK, ERROR };enum Status result; // Must write "enum" every timeWith typedef ✓
typedef enum { OK, ERROR } Status;Status result; // Cleaner!1#include <stdio.h>23// Method 1: typedef after enum4enum _Direction { NORTH, SOUTH, EAST, WEST };5typedef enum _Direction Direction;67// Method 2: typedef inline (preferred)8typedef enum {9 LOW,10 MEDIUM,11 HIGH,12 CRITICAL13} Priority;1415int main() {16 Direction heading = NORTH;17 Priority level = HIGH;18 19 printf("Heading: %d, Priority: %d\n", heading, level);20 21 return 0;22}06Enum Memory Size
In C, enums are stored as integers. The size is typically sizeof(int) = 4 bytes.
1#include <stdio.h>23typedef enum { A, B, C } SimpleEnum;4typedef enum { X = 1000000000 } LargeEnum;56int main() {7 printf("Size of int: %zu bytes\n", sizeof(int));8 printf("Size of SimpleEnum: %zu bytes\n", sizeof(SimpleEnum));9 printf("Size of LargeEnum: %zu bytes\n", sizeof(LargeEnum));10 11 // Enum variable size12 SimpleEnum e = A;13 printf("Size of enum variable: %zu bytes\n", sizeof(e));14 15 return 0;16}Typical Output:
Size of SimpleEnum: 4 bytes
Size of LargeEnum: 4 bytes
Size of enum variable: 4 bytes
Note
Unlike some other languages, C enums always use at least sizeof(int) bytes, even if you only have 2-3 values. The compiler doesn't optimize the size.
07Best Practices
✓ Use UPPERCASE for enum constants
enum Color { RED, GREEN, BLUE }; // Good - clear constantsenum color { red, green, blue }; // Works, but less conventional✓ Add a COUNT constant for iteration
typedef enum { APPLE, BANANA, ORANGE, FRUIT_COUNT // = 3, useful for loops/arrays} Fruit;const char* fruitNames[FRUIT_COUNT] = {"Apple", "Banana", "Orange"};✓ Add prefix to avoid naming conflicts
// Without prefix - might conflict with other codeenum { RED, GREEN, BLUE };// With prefix - saferenum Color { COLOR_RED, COLOR_GREEN, COLOR_BLUE };enum State { STATE_IDLE, STATE_RUNNING, STATE_STOPPED };Don't assume enum values
// BAD: Assuming valuesif (day >= 0 && day <= 6) { /* risky */ }// GOOD: Use the actual constantsif (day >= SUNDAY && day <= SATURDAY) { /* safe */ }!Code Pitfalls: Common Mistakes & What to Watch For
copied code often misuses enums in ways that look correct but cause subtle bugs. Here are the traps to watch for:
Copied code often assumes enum values are validated
C doesn't enforce enum values! Copied code often writes switch statements without default cases, assuming only valid enum values are passed. But enum Day d = 100; compiles fine!
Watch out: enums are just integers
Beginners sometimes treat enums like they have type safety. You can assign any integer to an enum, compare enums of different types, or do arithmetic on them. C won't warn you!
Beginners often create conflicting enum names
Enum constants are global in scope. Copied code might generate enum Color { RED } and enum Alert { RED } in different files, causing linker errors or unexpected behavior.
Code often uses enums for bit flags incorrectly
Copied code often mixes up sequential enums (0, 1, 2...) with power-of-two flags (1, 2, 4...). Using enum { A=1, B=2, C=3 } for bitwise operations creates bugs since 1|2=3=C, making the flags indistinguishable.
09Frequently Asked Questions
Q:Are enums just integers? Can I use them interchangeably?
A: Yes, enums are integers in C. You can assign an enum to an int, use them in arithmetic, and compare with numbers. However, using enum names makes code more readable and self-documenting. The compiler won't stop you from assigningday = 100 even if that's not a valid enum value.
Q:Why use enums instead of #define constants?
A: Enums provide: (1) Type safety — debuggers show enum names, not numbers, (2) Automatic numbering — no manual counting, (3) Scope — enums can be local to functions, #defines are global, (4) Grouping — related constants belong together. Use #define for string constants or compile-time calculations.
Q:Can I have two enum values with the same number?
A: Yes! This is called aliasing:enum Status { OK = 0, SUCCESS = 0 }. Both names refer to value 0. Useful for providing alternative names or backward compatibility.
Q:How do I print an enum name as a string?
A: C doesn't do this automatically. Common approaches: (1) Create a string array: const char* names[] = {"MONDAY", "TUESDAY"...}, (2) Use a switch statement returning strings, (3) Use X-macros for advanced cases. The enum stores only the number, not the name.
Q:What size is an enum?
A: Usually the same as int (4 bytes), but the C standard allows the compiler to choose. Some compilers use smaller sizes if the values fit. Use sizeof(enum Color) to check. For embedded systems or protocols requiring specific sizes, use explicit integer types instead.
09Summary
What You Learned:
- ✓Enum: Named integer constants for readable code
- ✓Default values: Start at 0, auto-increment by 1
- ✓Custom values: Assign any integer value
- ✓switch: Enums work great with switch statements
- ✓typedef: Create shorter type names
- ✓Size: Same as int (typically 4 bytes)
Test Your Knowledge
Related Tutorials
Data Types & Variables
Learn to store different kinds of data: numbers (int), decimals (float), and characters (char). Understand how much memory each type uses.
Variable Scope: Local vs Global
Understand where variables can be accessed in your program. Learn the difference between local and global scope, block scope, variable shadowing, and best practices for clean code.
Types of Errors in C
Master debugging! Learn all error types: Syntax, Semantic, Linker, Runtime, Logical, and Unreachable Code errors with examples and fixes.
Have Feedback?
Found something missing or have ideas to improve this tutorial? Let us know on GitHub!