Enumeration in C

In this tutorial, you will learn everything about another type of user-defined data type - enumerated data type in C. You will understand the need of enumeration in C and its basic facts with the help of simple examples.

What is enumerated data types in C?

Let us start by understanding the literal meaning of the word “ enumeration”. Enumeration means the process of mentioning a list of things one by one. In the programming world, an enumerated data type is simply a user-defined data type that consists of a set of named values. These named values are called enumerals. The keyword “enum” defines enumerated data types just like struct and union .

Syntax:

The prototype of the definition is:
 


enum flag { int_const1,int_const2, . . . . . , int_const n };
 

Here we have defined an enum named flag with n integer constants.These integer constants By default the value set by the compiler to int_const1 is 0, int_const2 is 1 and so on.

Let’s take an example


enum Status{unmarried, married ,divorced};

How to declare enumerated data types?

Like we did for other user data types, we can also create a variable for this user-defined data type enum in two different formats.

  1. During enumerator definition 

    
    enum flag { int_const1,int_const2, . . . . . , int_const n } Var;
    
    

    Example

    
    enum Status{unmarried, married ,divorced} S;
    
    
  2. Using the keyword enum inside main() function

    An alternative way to declare the enumerator is by declaring it inside the main function with the use of enum keyword,as we did for structure and union. The prototype is:

    
    enum flag Var;  // inside main function
    
    

    Here is the example that demonstrates the enum declaration.

    
    enum Status{unmarried, married ,divorced};
    
    int main()
    
    {
      enum Status S;
    }
    
    

In both cases, S is the variable we declared for the enum Status. This means the variable S can contain any of these values unmarried or married or divorced.

Automatic value assignment of ENUM

One among the interesting facts about enum is its automatic value assignment to its enumerals. More clearly the compiler will automatically assign the default values to the members in the order 0,1.2,...n when no value is explicitly given to the elements.


#include<stdio.h>

enum Status{unmarried, married ,divorced};

int main()

{
  enum Status S;
  S = married;
  printf("INTEGRAL CONSTANT OF MARRIED :%d",S);

  return 0;
}
 

Output:


INTEGRAL CONSTANT OF MARRIED :1

So in our example, unmarried is assigned with value 0, married with 1, and divorced with 2 by the compiler. Hence the output 1.

How to initialize enumerated data types?

However, users can change the default values and can set new values to the enum elements at the time of declaration, if needed . The initialization of enumerated type is as follows:


enum Status{unmarried = 3, married= 6 ,divorced = 5};
 

Example : How to initialize enumerated data types?


#include<stdio.h>

enum Status{unmarried =3, married=6 ,divorced=5};

int main()

{
  enum Status S;
  S = married;
  printf("INTEGRAL CONSTANT OF DIVORCED :%d",S);

  return 0;
}
 

Output:


INTEGRAL CONSTANT OF DIVORCED :5

In this example, we have explicitly assigned values to enum elements and hence it outputs the corresponding value.

Let's dive into some interesting facts on enum element initialization.

1. Same values can be initialized to multiple elements

In the above example, we have assigned different values to each element, so there arises a question: Is it possible to assign the same values to multiple enum elements. You will get the answer to this by reviewing the program given below.


#include<stdio.h>

enum Signal{Green = 1, Orange = 0, Red = 0};

int main()

{
  enum Signal S;
  printf("%d %d %d",Green, Orange, Red);

  return 0;
}
 

Output:


1 0 0

In the above code, both Orange and Red are assigned with values ‘0’. So we can conclude that in C  multiple enum names can have the same values.

2. Order of value assignment doesn’t matter 

The order of value assignment is not a big issue in enumerated data types. Enum offers better flexibility in the assignment of value so users can assign values to some elements and keep other elements unassigned. The unassigned elements take the value of the previous element plus one. 

Here is the example:


#include<stdio.h>

enum Rainbow{Violet= 22, Indigo , Blue = 2,Green = 7, Yellow,Orange,Red =18 };

int main()

{
  enum Rainbow R;
  printf("Violet = %d \nIndigo = %d \nBlue=%d\nGreen = %d\nYellow= %d\nOrange= %d\nRed = %d",Violet , Indigo, Blue,Green,Yellow, Orange, Red);

  return 0;
}

 

Output:


Violet = 22
Indigo = 23
Blue=2
Green = 7
Yellow= 8
Orange= 9
Red = 18

In the above example indigo, Yellow and Orange are unassigned values and they follow the value of their previous elements. Indigo follows the value of the Violet so it is assigned automatically with value 23(22+1). Similarly yellow and orange follow the value of Green which is 7 and hence set values 8 and 9 respectively.

3. Assigned value must be an integral constant

So far we have seen in all examples the values assigned to enum elements are integral constants and they worked perfectly. What if we assigned a value other than integral constant.


#include<stdio.h>

enum Rainbow{Violet= 22.55, Indigo , Blue = 2,Green = 7, Yellow,Orange,Red =18 };

int main()

{
  enum Rainbow R;
  printf("Violet = %d \nIndigo = %d \nBlue=%d\nGreen = %d\nYellow= %d\nOrange= %d\nRed = %d",Violet , Indigo, Blue,Green,Yellow, Orange, Red);

  return 0;
}

 

Output:

error: enumerator value for 'Violet' is not an integer constant|

We slightly changed the previous example by providing a non-integral value to enum values. Here Violet is assigned with value ‘22.55’ which is a non-integral value and hence the output is an error as given above.

So from this result, we can conclude that enum data types are type constrained and will take only integral constants as their element and the value range must be in between minimum integer value and maximum integer value possible.

Enumeration and Scope Rule

Enumerators follow the scope rules in the sense each enumerator must be distinct. The enum constants in each enumerator must be unique and if two different enumerators have the same enum constant, then the program will end up in error.

Here is the example:


#include<stdio.h>

enum color{Green, Yellow,Blue };
enum signal{Green,Orange ,Red};

int main()

{
  enum color C;
  enum signal S;

}

 

Output:


error: redeclaration of enumerator 'Green'|

ENUM VS #DEFINE

ENUM #DEFINE

Syntax


enum Signal { Green , Orange, Red};
 

Syntax


#define Green 0
#define Orange 1
#define Red 2
 
Enum is a user defined data type which assigns name to an integral constant #define is a macro preprocessor directive which substitutes a token with a  value. 
Enum is executed by the compiler  #define is executed by the preprocessor and is not visible by the compiler
Enum is type constrained i. E type of enum is always signed int. #define is can be of any type.
Enum follows scope rules  #define does not follows scope rule
Enum offers automatic value assignment. #define offers explicit value assignment.