Friday, August 17, 2012

Using Enumerations in ANSI C

In ANSI C, a enumeration is a collection of integer constants which share something in common.  The enumeration is somewhat of an analogy to a set. Also, enumerations are a better alternative than a group of macrodefinitions.

They can be declared as:
#include<stdio.h>

enum Color
{
   RED ,
   GREEN ,
   BLUE ,
};

int main(void)
{
   printf("RED = %d\nGREEN = %d\nBLUE = %d",RED,GREEN,BLUE);
   return 0;
}
/*Output:
RED = 0
GREEN = 1
BLUE = 2
*/
The constant RED will be initialized by default with 0, GREEN will be initialized with RED+1 (1) and BLUE will be initialized with (GREEN+1).
Using macrodefinitions, the program above would've looked like this:
#include<stdio.h>

#define RED   0
#define GREEN 1
#define BLUE  2

int main(void)
{
   printf("RED = %d\nGREEN = %d\nBLUE = %d",RED,GREEN,BLUE);
   return 0;
}
/*Output:
RED = 0
GREEN = 1
BLUE = 2
*/
Alternatively, if you initialize the enumeration in this way:
#include<stdio.h>

enum Color
{
   RED = 5,
   GREEN,
   BLUE,
};

int main(void)
{
   printf("RED = %d\nGREEN = %d\nBLUE = %d",RED,GREEN,BLUE);
   return 0;
}
/*Output:
RED = 5
GREEN = 6
BLUE = 7
*/
The constant RED will be initialized with 5, GREEN will be initialized with RED+1 (6)  and BLUE will be initialized with GREEN+1 (7).
TIPYou can can also initialize all members of the enumeration with non-default values:
#include<stdio.h>

enum Color
{
   RED = 5,
   GREEN = 7,
   BLUE = 3,
};

int main(void)
{
   printf("RED = %d\nGREEN = %d\nBLUE = %d",RED,GREEN,BLUE);
   return 0;
}
/*Output:
RED = 5
GREEN = 7
BLUE = 3
*/
TIPIf you don't initialize the first member of the enumeration, he will be equal to 0 by default even if you initialize other members:
#include<stdio.h>

enum Color
{
   RED ,
   GREEN ,
   BLUE =7,
};

int main(void)
{
   printf("RED = %d\nGREEN = %d\nBLUE = %d",RED,GREEN,BLUE);
   return 0;
}
/*Output:
RED = 0
GREEN = 1
BLUE = 7
*/
If you want to declare a Color variable you will have to put the keyword enum in front of it:
#include<stdio.h>

enum Color
{
   RED ,
   GREEN ,
   BLUE =7,
};

int main(void)
{
   enum Color myColor = RED;
   switch(myColor)
   {
      case RED:
           puts("My color is red");
           break;
      case GREEN:
           puts("My color is green");
           break;
      case BLUE:
           puts("My color is blue");
           break;
   }
   return 0;
}
/*Output:
My color is red
*/
Alternatively, if you want a shorter declaration you could use typedef:
#include<stdio.h>

enum Color
{
   RED ,
   GREEN ,
   BLUE =7,
};

typedef enum Color eColor;

int main(void)
{
   eColor myColor = RED;
   switch(myColor)
   {
      case RED:
           puts("My color is red");
           break;
      case GREEN:
           puts("My color is green");
           break;
      case BLUE:
           puts("My color is blue");
           break;
   }
   return 0;
}
/*Output:
My color is red
*/
TIPA shorter version of the declaration above is:
#include<stdio.h>

typedef enum
{
   RED ,
   GREEN ,
   BLUE =7,
}eColor;

int main(void)
{
   eColor myColor = RED;
   switch(myColor)
   {
      case RED:
           puts("My color is red");
           break;
      case GREEN:
           puts("My color is green");
           break;
      case BLUE:
           puts("My color is blue");
           break;
   }
   return 0;
}
/*Output:
My color is red
*/
TIPAlso, multiple members of an enumeration can have the same constant value:
#include<stdio.h>

typedef enum
{
   RED    = 0,
   GREEN  = 1,
   BLUE    =1,
}eColor;

int main(void)
{
   puts("This WILL NOT trigger an error");
   printf("RED = %d\nGREEN = %d\nBLUE = %d",RED,GREEN,BLUE);
   return 0;
}
/*Output
This WILL NOT trigger an error
RED = 0
GREEN = 1
BLUE = 1
*/
TIPA debugger may be able to print values of enumeration variables in their symbolic form.

PITFALLA common error that you may encounter while working with enumeration is the enumerator redeclaration as in the example below.
#include<stdio.h>

typedef enum
{
   RED    = 0,
   GREEN  = 1,
   BLUE    =1,
}CarColor;

typedef enum
{
    RED,        //RED is redeclarated
    YELLOW,
    MAGENDA
}WallColor;

int main(void)
{
   puts("This WILL NOT trigger an error");
   printf("RED = %d\nGREEN = %d\nBLUE = %d",RED,GREEN,BLUE);
   return 0;
}
/*Output
../main.c:20:5: error: redeclaration of enumerator ‘RED’
*/
TIPThe easiest way to solve such an issue is to adopt the following notation for enumerators: EnumName_EnumeratorDescription.
#include<stdio.h>

typedef enum
{
   CARCOLOR_RED    = 0,
   CARCOLOR_GREEN  = 1,
   CARCOLOR_BLUE   = 1,
}CarColor;

typedef enum
{
   WALLCOLOR_RED,        
   WALLCOLOR_YELLOW,
   WALLCOLOR_MAGENTA
}WallColor;

int main(void)
{
   printf("RED = %d\nGREEN = %d\nBLUE = %d",
           CARCOLOR_RED,CARCOLOR_GREEN,CARCOLOR_BLUE);
   return 0;
}
/*Output
RED = 0
GREEN = 1
BLUE = 1
*/
In conclusion, enumerations provide a convenient way to associate constant values with names as a more elegant alternative to multiple #define.

Question: What other pitfalls regarding enums do you know?

References:
http://tigcc.ticalc.org/doc/keywords.html#enum
http://en.wikipedia.org/wiki/Enumerated_type#C_and_syntactically_similar_languages
http://cplus.about.com/od/introductiontoprogramming/p/enumeration.htm
http://msdn.microsoft.com/en-us/library/whbyts4t.aspx

No comments:

Post a Comment

Got a question regarding something in the article? Leave me a comment and I will get back at you as soon as I can!

Related Posts Plugin for WordPress, Blogger...
Recommended Post Slide Out For Blogger