Enumeration enum learning notes

references:

[1] C++ Programming Language (Special Edition), translated by Qiu Zongyan, Machinery Industry Press

[2] C++ Primer (3rd Ed.), SB Lippman and J. Lajoie, People's Posts and Telecommunications Press

 

1. A simple example of the use of enumeration enum

      When writing a program, we often need to associate a set of alternative attributes with an object. For example, students' grades are A, B, C, D, etc., and the weather is divided into sunny, cloudy, rainy, etc.

      More commonly, opening a file may have three states: input, output and append. A typical approach is to define three constants correspondingly, namely:

      const int input = 1;

      const int output = 2;

      const int append = 3;

Then, call the following function:

      bool open_file(string file_name, int open_mode);

for example,

    open_file("Phenix_and_the_Crane", append);

       This method is relatively simple, but there are many disadvantages. The main point is that the value range of the second parameter passed to the open_file function cannot be limited. As long as the value of type int is passed, it is legal. (Of course, the countermeasure in this case is to judge the value of the second parameter inside the open_file function, and only process it within the range of 1, 2, and 3.)

       Using enumeration can alleviate this embarrassment to a certain extent (Note 1). It can not only realize the function similar to the definition of three constants before, but also combine these three values ​​into a unique group. For example:

      enum open_modes {input = 1, output, append};

      The above defines open_modes as enumeration type enumeration type. Each named enumeration is a unique type, which is a type specifier. For example, we can rewrite an open_file function:

      bool open_file(string file_name, open_modes om);

      In the open_modes enumeration, input, output, and append are called enumerators, which limit the value range of the objects defined by open_modes. At this time, calling the open_file function is exactly the same as the previous method: 

     open_file("Phenix_and_the_Crane", append);

     However, if the second parameter passed to open_file is not an open_modes enumeration type value (Note 1), then the compiler will recognize an error; even if the value of the parameter is equivalent to one of input, output, append,

It can also go wrong! For example:

     open_file("Phenix_and_the_Crane", 1);

2. Definition of enumeration

      An enumeration is a type that can hold a set of values ​​characterized by the user. Definitions and the like, enums are used much like an integer type.

The definition of an enumeration has the following form, that is, starting with the keyword enum, followed by an optional enumeration name, followed by curly braces {} containing a enumerators list separated by commas:

      enum [enumeration name] {enumerator1[=value1], enumerator2[=value2], ...};

3. The type and value of the enumerator

      The type of enumerator is the enumeration it is in. For example, in the open_modes enumeration mentioned above, the types of enumerators such as input, output and append are all open_modes. This is done to give the user and the compiler some hint about the proposed use of the variable.

      By default, the first enumerator is assigned a value of 0, and the value of the next enumerator is the value of the previous enumerator + 1, for example:

      enum weather {sunny, cloudy, rainy, windy};

in

     sunny == 0, 

      cloudy == 1,

      rainy == 2,

      windy == 3;

       The above is the default situation. Sometimes we want to explicitly specify the value of an enumerator, so what happens? have a look:

       enum some_fruit {apple = 3, orange, banana = 4, bear};

       Ok, apple == 3, banana == 4; what about orange and bear? Remember what I said before, by default, "the value of the next enumerator is the value of the previous enumerator + 1". Since these two enumerators are not explicitly assigned, then follow the default rules, so orange == 4, bear == 5. 

       It can also be seen from this example that the values ​​of the enumerators in the same enumeration do not need to be unique. What is the use of this? Here is a simple example:

       enum some_big_cities {

                                               Guangzhou = 4, 

                                                Shenzhen    = 4, 

                                               Hongkong   = 4, 

                                               Shanghai    = 2, 

                                               Beijing         = 3, 

                                               Chongqi = 3

                                           };

The above simply classified the five cities according to the regions in South China (4), East China (2), and North China (3).

4. Definition, initialization and assignment of enumeration variables

     Since every enumeration is a type, it is natural to declare variables from this type, for example, some_big_cities defined earlier:

     some_big_cities where_I_am;

     It should be noted that there is no initialization when declaring where_I_am, if the value of where_I_am is printed at this time: 

     enum some_big_cities {

                                            Guangzhou = 4, 

                                            Shenzhen = 4, 

                                            Hongkong = 4, 

                                             Shanghai = 2, 

                                            Beijing = 3, 

                                             Chongqi = 5};

int main(void)

      some_big_cities wh;

     cout<<"the value is: "<<wh<<endl;

     return 0;

}

The output will be that the value is: 1. However, if you declare wh as a global variable, the other case:

enum some_big_cities {Guangzhou = 1 Shenzhen = 1, Hongkong = 1, 

                                       Shanghai = 2, Beijing = 3, Chongqi = 5};

some_big_cities wh;

int main(void)

   cout<<"the value is: "<<wh<<endl;  

   return 0;

}

The output will be the value is: 0;

      The above results were obtained in Visual C++ 2005 Express. I don't know how other compilers are doing, and I don't know why I got such results. Come down and look for information.

     When defining an enum variable, you can initialize it, for example:

     some_big_cities wh = Guangzhou;

     Note that only one of the enumerators can be used on the right side of the equal sign; in particular, taking Guangzhou as an example, although Guangzhou==4, the following initialization is wrong:

     some_big_cities wh = 4;

     Visual C++ 2005 compiler hint:

        error C2440: 'initializing' : cannot convert from 'int' to 'some_big_cities'

      It can be seen that you cannot directly assign an integer to an enumeration variable, because enumeration and integer are of different types unless explicitly converted. The relationship between enumeration and integer will be discussed later.

      In addition to initialization, enumeration variables also have assignment operations:

     some_big_cities wh;

     wh = Guangzhou;

     wh = Shanghai;

or

    some_big_cities wh1 = Guangzhou;

    some_big_cities wh2 = Shanghai;

    wh2 = wh1;

5. The value range of the enumeration

   If the values ​​of all enumerators in an enumeration are non-negative, the representation range of the enumeration is [0:2^k-1], where 2^k can make all enumerators fall within this range The smallest power of 2; if there is a negative enumeration value, the value range of the enumeration is [-2^k, 2^k-1]. For example:

   enum e1 {dark, light}; // range 0:1

    enum e3 {min = -10, max = 1000}; // range -1024:1023

6. The relationship between enumeration and integer

    An integer value can only be explicitly converted to an enumeration value, however, if the result of the conversion is outside the range of the enumeration value, the result is undefined.

     enum e1 {dark = 1, light = 10};

     e1 VAR1 = e1(50); //undefined

     e1 VAR2 = e1(3); //Compile passed

     This also explains why implicit conversions from integers to enumerations are not allowed, because most integer values ​​have no corresponding representation in a particular enumeration. 

      As for the example that the enumeration can be used as a specific integer number, you can experience it from open_modes.

7. Custom operators

      Enumeration is a user-defined type, so users can define their own operations for it, such as ++ or <<, etc. However, before it is defined, it cannot be used by default because the enumeration is like an integer, for example:

   enum SomeCities

{

   zhanjiang,

   Maoming,

   Yangjiang,

   Jiangmen,

   Zhongshan

};

SomeCities oneCity;

for (oneCity = zhanjiang; oneCity != Zhongshan; ++oneCity)

{

   cout<<oneCity<<endl;

}

 

The above ++OneCity is not defined, and the following error is obtained under Visual C++ 6 compilation:

error C2675: unary '++' : 'enum main::SomeCities' does not define this operator or a conversion to a type acceptable to the predefined operator

 

8、Sizeof

    The sizeof of an enumeration type is the sizeof of an integer that can accommodate its range, and will not be greater than sizeof(int), unless the value of an enumerator cannot be represented by int or unsigned int.

      On 32-bit machines, sizeof(int) is generally equal to 4. All enumerations described earlier, for example,

enum SomeCities

{

   zhanjiang,

   Maoming,

   Yangjiang,

   Jiangmen,

   Zhongshan

};

 

Calculate its sizeof, which may be 1 or 4. On my intel E2160 dual-core, 32-bit machine, I get 4.

-----------------------------------------------------------------------------------

[Note 1, Begin]

Since it is possible to obtain the value of the corresponding enumeration type by explicitly converting the integer number, it is still not enough to declare an enumeration to limit the value range of the parameters passed to the function. The following is an example:

enum SomeCities

{

zhanjiang=1, //1

Maoming, //2

Yangjiang, //3

Jiangmen, //4

Zhongshan = 1000 //1000

};

void printEnum(SomeCities sc)

{

cout<<sc<<endl;

}

int main(void)

{

SomeCities oneCity = SomeCities(50); // Assign 50 to oneCity through explicit conversion 

printEnum(oneCity); //Get 50 output under VC++ 6 compiler

return 0;

}

 

The above example shows that although there is no enumeration value assigned to 50 in the definition of SomeCities, since 50 is within the value range of the enumeration, a defined enumeration value is obtained through explicit declaration, and successfully passed to printEnum function.

Guess you like

Origin blog.csdn.net/yangchaojjyy/article/details/128700313