Page Content

Tutorials

What Are The Enumeration In C With Code Examples?

Enumeration in C

A user-defined data type in C that offers a means of characterizing a range of values represented by named constants known as enumerators is called an enumerated type. The keyword enum is used for this. Compared to utilizing raw integer values, the main goal of enumerated types is to construct a set of named integer constants, which can make code more intelligible and self-documenting. Additionally, they offer type checking defined by the compiler.

The enum keyword, an optional tag name, and a list of enumerators encapsulated in curly brackets {} comprise an enumerated type description.

For card suites, for instance, you can define an enumeration called suits with named values:

enum suits {clubs, diamonds, hearts, spades};

The enumeration type enum suits are defined here. The enumerators are the identifying symbols, which are clubs, diamonds, hearts, and spades.

Enumeration identifiers are handled by the compiler as integer constants by default. The compiler gives each name in the list a sequential integer value, starting with 0, starting with the first name. Clubs would be 0, diamonds 1, hearts 2, and spades 3 in the aforementioned suit example.

The assignment operator = Can be used to explicitly assign particular integer values to enumerators. Sequential integer values are assigned to the list’s subsequent identifiers, starting with the assigned value plus 1. For example, to count months beginning with 1:

enum month { January = 1, February, March, April, May, June,
             July, August, September, October, November, December };

January is 1 in this instance, February is 2, and so forth, with December being 12. Although their identifiers must be distinct inside the same scope, several enumerators may share a constant value.

You can declare variables of an enumerated type after it has been defined. You declare variables using the enum keyword, the tag name, and the variable name if the enumeration includes a tag name (such as suits or month):

enum month aMonth;
enum suits card;

Additionally, if the enumeration is unnamed, you can define variables right after the enumeration definition:

enum { east, west, south, north } direction; // Unnamed enum, variable 'direction' declared here

One of the enumerator names is used to assign a value to an enumeration variable:

aMonth = February; // Assigns the integer value corresponding to February 
direction = west;

The implicit integer value of a variable of an enumeration type is shown when printf is used to print it:

printf("Month number: %d\n", aMonth); // Prints 2
printf("Direction value: %d\n", direction); // Prints the integer value assigned to 'west' (1 by default)

In switch statements, where the named enumerators can be utilized as case labels, enumerations are especially helpful.

// Example using enum month in a switch statement 
enum month aMonth;
int days;

Example

#include <stdio.h>
// Assuming your enum is defined something like this:
typedef enum {
    January = 1, // Start from 1 for month numbers
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
} Month;
int main() {
    int monthNumber; // Use an int for raw input
    Month aMonth;
    int days;
    printf("Enter month number: ");
    if (scanf("%i", &monthNumber) != 1) {
        printf("Invalid input. Please enter a number.\n");
        return 1; // Indicate error
    }
    // Validate the input number against expected enum range
    if (monthNumber >= January && monthNumber <= December) {
        aMonth = (Month)monthNumber; // Explicit cast after validation
    } else {
        aMonth = -1; // Or some other invalid indicator if your enum allows it,
                     // or just rely on the default case for invalid numbers.
                     // For month enums, it's often better to just let the switch handle it.
    }
    switch (aMonth) {
        case January:
        case March:
        case May:
        case July:
        case August:
        case October:
        case December:
            days = 31;
            break;
        case February:
            days = 28; // Simplified for example, real logic needs leap year
            break;
        case April:
        case June:
        case September:
        case November:
            days = 30;
            break;
        default:
            days = -1; // Indicate an error for numbers outside enum range
            break;
    }
    if (days != -1) {
        printf("Number of days: %d\n", days);
    } else {
        printf("Invalid month number.\n");
    }
    return 0;
}

Output

Enter month number: 1
Number of days: 31

To limit the range of values that can be supplied to the function, they can also be utilized as function parameters:

void stack(enum suits card) {
    // we know that card is only one of four values 
    // ... function logic ...
}

Declaring variables without using the enum keyword again is made possible by the typedef statement, which is frequently used with enumerated types to construct an alias.

Example

#include <stdio.h>
typedef enum month {January = 1, February, March, April, May, June, July, August, September, October, November, December} MonthType;
MonthType currentMonth = July;
typedef enum day {sun, mon, tue, wed, thu, fri, sat} DayType;
DayType today = mon;
typedef enum {false, true} Boolean;
Boolean isValid = true;
int main() {
    printf("Current Month (numeric value): %d\n", currentMonth);
    printf("Today (numeric value): %d\n", today);
    printf("Is Valid (numeric value): %d\n", isValid);
    return 0;
}

Output

Current Month (numeric value): 7
Today (numeric value): 1
Is Valid (numeric value): 1

Enumerations can also be used as members within structures.

Example

#include <stdio.h> // Include for printf
// Example struct using enum members (similar to struct date) [36]
typedef enum { January=1, February, March, April, May, June,
                 July, August, September, October, November, December } Month;
typedef enum { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } DayOfWeek;
struct date {
    Month       month;
    DayOfWeek   day;
    int         year;
};
int main() { // main function is required for execution
    struct date holiday;
    holiday.month = December;
    holiday.day = Friday;
    holiday.year = 2024;
    printf("Holiday Date: Month %d, Day %d, Year %d\n", holiday.month, holiday.day, holiday.year);
    // You could also map numeric enum values back to strings for better readability
    // This would require an array of strings or a switch statement
    const char *monthNames[] = {"", "January", "February", "March", "April", "May", "June",
                                "July", "August", "September", "October", "November", "December"};
    const char *dayNames[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    printf("Holiday Date (readable): %s, %s %d\n", dayNames[holiday.day], monthNames[holiday.month], holiday.year);
    return 0;
}

Output

Holiday Date: Month 12, Day 5, Year 2024
Holiday Date (readable): Friday, December 2024

In conclusion, C’s enumerated types improve the readability and maintainability of code by offering a simple and type-safe method for defining and utilizing collections of linked integer constants. Despite being essentially integer types, it is regarded as best practice to use the enumerator names instead of their underlying integer values in order to take advantage of the type-checking and self-documenting features.

You can also read What Are The Basics Of File Handling In C?

You can also read What Is The C Error Handling During File Operations?

Agarapu Geetha
Agarapu Geetha
My name is Agarapu Geetha, a B.Com graduate with a strong passion for technology and innovation. I work as a content writer at Govindhtech, where I dedicate myself to exploring and publishing the latest updates in the world of tech.