Enum (Enumeration) in C

This article is the continuation of the Series on the C programming tutorial and carries the discussion on C language programming and its implementation. It aims to provide easy and practical examples for understanding the C program. In our last article, we have seen the Typedef in C programming. In this tutorial, we are going to discuss Enumeration in C language.

You can also read, Embedded interview topics, Types of Pointers in C, Pointers – 1, Pointers – 2, and typecasting in C.

The enumeration in C Language Tutorial

Introduction

Enumerated Types are a special way of creating your own Type in C. The type is a “list of keywords”. Enumerated types are used to make a program clearer to the reader/maintainer of the program. For example, say we want to write a program that checks for keyboard presses to find if the down arrow or up arrow has been pressed. We could say: if( press_value == 32 ).   32 is the computer’s representation of the down arrow. Or, we could create our own enumerated type with the keywords: down_arrow and up_arrow. Then we could say: if( press_value ==down_arrow ). This second version is much more readable and understandable to the programmer.

Enumerated Types 

Enumerated Types allow us to create our own symbolic names for a list of related ideas. The keyword for an enumerated type is enum. For example, we could create an enumerated type for true and false (note: this is done for you by C and is type bool).

enum Boolean
{
    false,
    true
};

We could also create an enumerated type to represent various security levels so that our program could run a door card reader:

enum Security_Levels
{
  black_ops,
  top_secret,
  secret,
  non_secret
}; // don't forget the semi-colon ;

These enumerated types can be used like any other type in a program. The type name “Boolean” or “Security_Levels” can be used to define variables or the return type of functions. The actual enumerations can be used directly in the code. For example:

int main( int number_of_args, char* arg_list[] )
{
    Security_Levels my_security_level = top_secret;
    if ( my_security_level == black_ops ) {
        printf("Welcome Mister Bond\n");
        open_safe();
        open_door();
     } else if ( my_security_level == top_secret ) {
         printf("Welcome Q\n");
         open_door();
     } else if ( my_security_level == secret ) {
         printf("Please leave Now\n");
     } else if ( my_security_level == non_secret ) {
         printf("Warning, The Police have been Called\n");
         printf("Surrender yourself to them immediately!\n");
         call_police();
     }
     return 0;
}

In Essence, Enumerated types provide a symbolic name to represent one state out of a list of states.

Enumerated Types are Not Strings

It bears repeating: Even though enumerated type values look like strings, they are new keywords that we define for our program. Once defined the computer can process them directly. There is no need to use strcmp with enumerated types.

// CORRECT:

if ( my_security_level == secret ) ...

// INCORRECT:

if ( ! strcmp(my_security_level,secret) ) ...

// ALSO INCORRECT:

if ( ! strcmp(my_security_level,"secret") ) ...

Enums are Not (Really) Integers

It turns out that enumerated types are treated like integers by the compiler. Underneath they have numbers 0,1,2,… etc. You should never rely on this fact, but it does come in handy for certain applications.

For example, our security_levels enum has the following values:

black_ops = 0
top_secret = 1
secret = 2
non_secret = 3

Printing the “string” representation of the type

Note: One of the shortcomings of Enumerated Types is that they don’t print nicely. To print the “String” associated with the defined enumerated value, you must use the following cumbersome code:

if ( my_security_level == secret ) {
    printf("secret");
} else if ( my_security_level == top_secret ) {
    printf("top_secret");
}
...

An Enum String Printing Trick

The following “trick” to print enums (in a more compact notation) is made possible because of the following two facts:

  1. C arrays are based on index 0.
  2. enums have a “built-in” integer value starting at 0.

The trick is to create an array of strings and use the enums to index the array. Here is an example of how it is done:

// ONLY use for PRINTING
const char* Security_Levels_Strings[] = {"Black Ops", "Top Secret", "Secret", "Non Secret"};int main()
{
   Security_Levels s[4];
   s[0] = black_ops;
   s[1] = top_secret;
   s[2] = secret;
   s[3] = non_secret;
   printf("If enumerated types were integers they would be: \n");
   printf("\t%d %d %d %d \n\n", black_ops, top_secret, secret, non_secret );
   printf("Thus the array would contain: \n\t");
   for (int i=0; i<4; i++)
   {
       printf( "%d ", s[i] );
   }
   printf("\n\n");
   printf("To access the strings directly we can use:\n");
   printf("\tSecurity_Levels_Strings[0] is : '%s'\n", Security_Levels_Strings[0]);
   printf("\tSecurity_Levels_Strings[1] is : '%s'\n", Security_Levels_Strings[1]);
   printf("\tSecurity_Levels_Strings[2] is : '%s'\n", Security_Levels_Strings[2]);
   printf("\tSecurity_Levels_Strings[3] is : '%s'\n", Security_Levels_Strings[3]);
   printf("OR:\n");
   printf("\tSecurity_Levels_Strings[ black_ops ] is : '%s'\n", Security_Levels_Strings[black_ops]);
   printf("\tSecurity_Levels_Strings[ top_secret ] is : '%s'\n", Security_Levels_Strings[top_secret]);
   printf("\tSecurity_Levels_Strings[ secret ] is : '%s'\n", Security_Levels_Strings[secret]);
   printf("\tSecurity_Levels_Strings[ non_secret] is : '%s'\n", Security_Levels_Strings[non_secret]);
   printf("\nFinally, to get the strings associated with the stored values in our array we write:\n");
   for (int i=0; i<4; i++)
   {
       printf( "Security_Levels_Strings[s[%d]], which is '%s'\n", i, Security_Levels_String
       s[s[i]] );
   }
   return 0;
}

In our next tutorial, we will see Typecasting in C programming.

You can also read the below tutorials.

Linux Device Driver TutorialsC Programming Tutorials
FreeRTOS TutorialsNuttX RTOS Tutorials
RTX RTOS TutorialsInterrupts Basics
I2C Protocol – Part 1 (Basics)I2C Protocol – Part 2 (Advanced Topics)
STM32 TutorialsLPC2148 (ARM7) Tutorials
PIC16F877A Tutorials8051 Tutorials
Unit Testing in C TutorialsESP32-IDF Tutorials
Raspberry Pi TutorialsEmbedded Interview Topics
Reset Sequence in ARM Cortex-M4BLE Basics
VIC and NVIC in ARMSPI – Serial Peripheral Interface Protocol
STM32F7 Bootloader TutorialsRaspberry PI Pico Tutorials
STM32F103 Bootloader TutorialsRT-Thread RTOS Tutorials
Zephyr RTOS Tutorials – STM32Zephyr RTOS Tutorials – ESP32
AUTOSAR TutorialsUDS Protocol Tutorials
Product ReviewsSTM32 MikroC Bootloader Tutorial
VHDL Tutorials
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Table of Contents