Thread: Could someone please clarify enums for me

  1. #1
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128

    Could someone please clarify enums for me

    Hi everyone,

    I am messing about with enums and trying to understand what they are actually used for. I came up with the following 2 programs, none of which demonstrate very well to me the point of enums:

    Code:
    #include <iostream>
    #include <string>
    
    int main()
    {
        enum TrafficLightColor_t {RED, YELLOW, GREEN};
    
        TrafficLightColor_t currentColour;
        //How do I get different values into my new variable currentColour to utilise the following switch?
        
        switch(currentColour)
        {
            case RED: //How do I get currentColour to equal 'RED'
                std::cout << "I am red";
                break;
            case YELLOW: //How do I get currentColour to equal 'YELLOW'
                std::cout << "I am yellow";
                break;
            case GREEN: //How do I get currentColour to equal 'GREEN'
                std::cout << "I am green";
                break;
            default:
                break;
        }
    }
    The other one was:

    Code:
    #include <iostream>
    #include <string>
    
    int main()
    {
        enum TrafficLightColor_t {RED = 1, YELLOW, GREEN};
    
        int currentColour;
        
        std::cout << "Enter a number. 1=RED, 2=YELLOW and 3=GREEN: ";
        std::cin >> currentColour;
        
        switch(currentColour)
        {
            case RED:
                std::cout << "I am red";
                break;
            case YELLOW:
                std::cout << "I am yellow";
                break;
            case GREEN:
                std::cout << "I am green";
                break;
            default:
                break;
        }
    }
    After searching google for example programs, I still can't find an explanation that gives me a full overview.

    I understand the point of statements being easier to read i.e. if DEBUGGER_ON, if DEBUGGER_OFF, instead of if == 1, or if == 2 etc... (who knows what 1 or 2 does? Have to look it up).

    Any extra clarification is very much appreciated. Thanks.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Basically enums are to handle this, which happens every now and then: You start with a simple variable that can be on or off, so you use a bool. Then you realize it really has a third state, so you move to an int. Then you realize there are actually two more slightly different states you can be in, and it starts becoming hard to remember what the difference is between 0, 1, 2, 3, and 4. So you create an enum to represent the different values in a way you as the programmer can remember.

    In other languages you might start representing this state as a string, and you can do that in C++ too, but enums are compile-time constants and can be compared, assigned, copied, etc at the same speed as a single number. Which is much faster than comparing, copying, etc a string. Whenever you have a state inside your program that doesn't need to be displayed as a string to the user, or parsed from a file, etc, you may want to use an enum.

    I tried to find a real-world example that's easy to understand... the best I could find is this: encoding.h
    That's part of the libxml parsing library, which reads XML (which is very similar to the HTML used to create web pages). Basically, XML files (like many files) can be specified in many different encodings, which means a way of interpreting the data in the file. For example, straight ASCII text like this post uses one byte per character you can see, and there is an ASCII encoding which says "32 means space", "65 means 'A'", etc. If your file is in a different language it might be in unicode, where there are two bytes per character (and this lets you write Chinese symbols etc). Libxml reads the encoding which is specified in an XML or HTML file, presumably in text, then converts it internally to an enum representation of the same thing. Because it's more efficient for comparison, and also because it lets them specify a standard interface for the library which they can stick with, and when new encodings are created they can just add one more enum value.

    Enums aren't magical, you can do the same thing with int constants or #defines or strings. But enums are nice because they're checked at compile time, all possible values are laid out in a list (a string could really take on any value!). Just a nice language feature to have.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128
    Thanks, that's a great explanation. So I'm thinking enums are for the programmers benefit rather than the user, just making things easier to read (plus the other benefits you mentioned).

    Code:
    if (a == 34)
    {
    std::cout << "Start running!";
    }
    or like this, which may give a better clue of what's going on

    Code:
    if (a == GODZILLAS_COMING)
    {
    std::cout << "Start running!";
    }
    Ok, maybe I could have thought of a better example but I get the point

  4. #4
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    enum means 'enumerated list' and it is a very useful feature- you flag your constants with the enum and you have nice labels instead of magic numbers, and you can use it to get around things like in c++ does not allow strings as a control for a switch. Enum is defaulted to start at 0 - but you can override that if you wish. You can override the whole sequence but basically the members of the list are assigned value 0 to n sequentially.
    Last edited by rogster001; 04-21-2013 at 04:28 AM.
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  5. #5
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128
    Thanks for the comments, it's all very helpful. Still struggling a bit with enums, but working on it.

  6. #6
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    And just to confuse you a little bit more, here is a C++11 example you should try if you have got a recent compiler.
    Code:
    #include<iostream>
    
    enum class Colour {Red,Green,Blue};
    
    void foo(Colour c)
    {
        if(c==Colour::Red)
            std::cout<<"foo\n";
        else std::cout<<"bar\n";
    }
    
    int main()
    {
        foo(Colour::Red);
        foo(Colour::Blue);
        foo(Colour::Green);
    }
    There are a few advantages compared to traditional (C) enums , which you can research.

  7. #7
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    In addition to giving names to numbers, some compilers will produce warnings or errors if you try to use numbers or the wrong enum member when a variable or input is defined as an enum type.

  8. #8
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128
    I think I may have to find a video or something to see enums in action as something visual would certainly help. I am enrolled in a udemy online course which I hope will include enums so will start that soon. I am also working out of a couple of beginners books.

    It's such a huge subject so I'm trying to really keep myself from looking to far ahead so as to not get totally overwhelmed, and then demotivated. The two of those seem to go hand in hand for me.

  9. #9
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    It might help to consider an example with two enums:

    Code:
    enum color_t {red, yellow, green, orangec};
    enum fruit_t {apple, banana, orangef};
    Note that you can't redefine orange, so I added a suffix to avoid an error. Some compilers would prevent you from accidentally using a fruit name where you defined an input or variable as a color (or vice versa).

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by samwillc View Post
    I think I may have to find a video or something to see enums in action as something visual would certainly help. I am enrolled in a udemy online course which I hope will include enums so will start that soon. I am also working out of a couple of beginners books.

    It's such a huge subject so I'm trying to really keep myself from looking to far ahead so as to not get totally overwhelmed, and then demotivated. The two of those seem to go hand in hand for me.
    Honestly, the only thing I would remember is that enums are good where you have variables that can only have a set of fixed states.
    Storing information such as colours, gender, models (eg car model, etc) is a very good example of enums.
    Essentially, enums are integer variables where each state of the variable is a descriptive name. This makes it easier to read and write code. That is the main thing you should remember. You shouldn't focus on the rest of the details right now. Just make sure to use "enum class" when you are practising with them since regular "enum" is an older version of the feature available in older versions of the language.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128
    I'm trying hard to understand this (so I can use it in my tic tac toe game)! I will try to explain my problem a bit further. The thing I don't get is this:

    Code:
    #include <iostream>
    
    int main()
    {
        enum CarType {CT_FORD, CT_MUSTANG, CT_SKODA}; //not sure about using class yet
        
        CarType myCar = CT_FORD; //This is not very dynamic. How do I get different values into myCar? i.e. CT_MUSTANG
        
        if (myCar == CT_FORD) //how do you get to the point where myCar actually equals CT_FORD (or 0)?
        {
            std::cout << "You got a Ford"; //of course, because 'CarType myCar = CT_FORD' is hard-coded in!
        }
        else if (myCar == CT_MUSTANG)
        {
            std::cout << "You got a Mustang";
        }
        else
        {
            std::cout << "You got a Skoda";
        }
    }
    I think I am looking at enums the wrong way and trying to use them incorrectly as well, which is confusing me. I have added comments which hopefully show the steps that I am getting stuck on.

    Are they more a feature for a return value? i.e. if a function returns 323, it's easier to see a description/keyword rather than 323, which could mean anything, leading to you having to look it up somewhere amongst the code.

    Thanks for the patience everyone! Been looking at this: http://www.learncpp.com/cpp-tutorial...merated-types/
    Last edited by samwillc; 04-21-2013 at 02:26 PM.

  12. #12
    Registered User
    Join Date
    Apr 2011
    Posts
    62
    //This is not very dynamic. How do I get different values into myCar? i.e. CT_MUSTANG
    Code:
    #include <iostream>
    
    int main()
    {
        enum CarType {CT_FORD, CT_MUSTANG, CT_SKODA}; //not sure about using class yet
    
        CarType myCar = CT_FORD; //This is not very dynamic. How do I get different values into myCar? i.e. CT_MUSTANG
    
        if (myCar == CT_FORD) //how do you get to the point where myCar actually equals CT_FORD (or 0)?
            std::cout << "You got a Ford"; //of course, because 'CarType myCar = CT_FORD' is hard-coded in!
        if (myCar == CT_MUSTANG)
            std::cout << "You got a Mustang";
        myCar=CT_SKODA;
        if (myCar == CT_SKODA)
            std::cout << "You got a Skoda";
    }
    the main advantage of enums comes when you have multiple diferent actions that may or may not be used. traditionaly (meaning: when done by stuborn programmers like myself who use ints for everything even when we shouldnt) you would need to remember the correspondence between the value of your int and the option to use, so i could do something like this:

    Code:
    int main()
    {
        int coordenatesystem;  //controls the coordenate system used: 0 means Cartesian; 1 logaritmic; 2 polar; 3 cylindrican; 3 spheric 
        
        if (coordenatesystem==1)
            /*do something*/;
        if (coordenatesystem==3)
            /*do something else*/;
        
        //etc
        
        return 0;
    }
    notice that ill need to keep remembering what 0,1,2,3&4 mean, its not particulary reader friendly, I could easily switch a 3 for a 4. one thing to keep in mind is that in a large project things get edited halfway through so readbility becomes more and more important the larger the work...and another thing is the fact that nothing stops me (compiler-wise) from assigning 6 to the int.

    on the other hand using enums looks mutch clearer:

    Code:
    int main()
    {
        enum coordenatesystem{cartesian,polar,spheric};
        coordenatesystem coords;
        if (coords==cartesian)
            /*do something*/;
        if (coords==spheric)
            /*do something else*/;
    
        //etc
    
        return 0;
    }

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    [edit] Wrote this at the same time as killme, we're probably saying the same things... [/edit]

    Enums can be used for returning information from a function, passing information into a function, or storing data in structures, etc. What you've written is a simple example but it can only create one type of car. You can do something more complicated too...
    Code:
    enum CarType pickCarType(const std::string &userInput) {
        if(userInput.length() > 0 && userInput[0] == 'F') {
            // if user input starts with an F, assume they really want a Ford
            return CT_FORD;
        }
    
        // otherwise, give them a random car type
        if(std::rand() % 2 == 0) return CT_MUSTANG;
        else return CT_SKODA;
    }
    The if-else statement I wrote at the end could also be written as a switch statement, if you know what those are,
    Code:
        switch(std::rand() % 2) {
        case 0: return CT_MUSTANG;
        case 1: return CT_SKODA;
        }
    which suggests a nicer solution: treat the number *as* an enum value.
    Code:
    enum CarType pickCarType(const std::string &userInput) {
        if(userInput.length() > 0 && userInput[0] == 'F') {
            // if user input starts with an F, assume they really want a Ford
            return CT_FORD;
        }
    
        // otherwise, give them a random car type
        int number = std::rand() % 2;
        return (enum CarType)(number + 1);  // cast the number to a CarType.
    }
    (I add 1 to skip over CT_FORD because I don't want to randomly pick a ford.) That's one other nice thing about enum values, they're just numbers, so you can write for loops to iterate over them, or generate them randomly, etc.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  14. #14
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128
    Thanks everyone. I will try the examples later after work.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    I note that for the scenarios that killme and dwks presented, encoding the type as an enum is not necessarily the best design choice, depending on the requirements. For example, it might be better to create a class hierarchy instead, and then deal with (smart) pointers/references to objects of the subclasses and override virtual functions instead of using an if-else chain to check the types via enum.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. asymptotic notation clarify
    By monkey_c_monkey in forum Tech Board
    Replies: 6
    Last Post: 10-05-2012, 06:12 PM
  2. Clarify pass by reference
    By monkey_c_monkey in forum C++ Programming
    Replies: 3
    Last Post: 08-29-2012, 10:01 PM
  3. Can someone clarify what a 'slow event' is.
    By Overworked_PhD in forum Networking/Device Communication
    Replies: 2
    Last Post: 01-13-2008, 05:11 PM
  4. Can someone clarify this comment.
    By Overworked_PhD in forum C Programming
    Replies: 2
    Last Post: 05-15-2007, 10:17 PM
  5. Clarify
    By Mr. Squirrel in forum Windows Programming
    Replies: 0
    Last Post: 12-02-2001, 04:35 PM