C++. Перечисления (enumerations). Ключевое слово enum. Преимущества использования перечислений. Примеры

Перечисления (enumerations). Ключевое слово enum. Преимущества использования перечислений. Примеры



Содержание


1. Общие сведения о перечислениях. Преимущества использования перечислений в программах

Тип данных «перечисление» используется для создания именованных идентификаторов, представляющих некоторое целочисленное константное значение.

Перечисления позволяют объединять группы константных значений в единое целое. Формируется тип перечисления на основании которого может быть объявлена переменная, которая принимает значение из набора, который описывается в перечислении.

При использовании перечислений в программах можно выделить следующие взаимосвязанные преимущества:

  • можно создавать разные типы перечислений, каждое из которых содержит группы констант которые формируются по некоторому признаку;
  • константы в перечислении группируются. Если в программе есть большие наборы констант, то это облегчает читабельность и дальнейшее сопровождение программы.

 

2. Общая форма объявления перечисления. Ключевое слово enum. Особенности работы перечисления

Чтобы объявить перечисление в языке C++ используется ключевое слово enum.

Общая форма объявления перечисления следующая:

enum TypeName
{
    name1 [=const1],
    name2 [=const2],
    ...
    nameN [=constN]
};

здесь

  • TypeName – имя типа перечисление (имя шаблона);
  • name1, name2, …, nameN – имена идентификаторов-констант, которые принимают соответственно значения const1, const2, …, constN. Необязательно идентификатора-константы должны принимать значение. Квадратные скобки [ ] означают, что константное значение может отсутствовать;
  • const1, const2, …, constN – необязательные значения, задающие значение константам, которые пересчитываются в перечислении.

Если значение константы в перечислении не задано, то оно принимает значение, которое есть на 1 больше чем предыдущее константное значение. Например, если предыдущая константа имела значение 5, то следующая будет иметь значение 6. В случае типа char следующая константа есть следующим символом в таблице символов.

После объявления типа (шаблона) перечисления, можно объявлять переменные этого типа, например

TypeName varName;

здесь

  • TypeName – имя ранее объявленного типа (шаблона) перечисления;
  • varName – имя переменной типа TypeName.

Если объявлена переменная, то эта переменная в программе может принимать значение имени из перечисления, например

varName = name2;

 

3. Каким образом в перечислении можно задать значение перечислительным константам? Пример

Значение перечислительным константам можно задать одним из двух способов:

  • с помощью явной инициализации. В этом случае, после имени константы ставится знак равно = и значение, которое принимает данная константа;
  • по умолчанию. В этом случае первой константе ставится в соответствие 0, а каждая последующая константа принимает значение на 1 больше.

Пример.

// явная инициализация
enum DAYS_IN_MONTHS {
    January = 31,
    February = 28,
    March = 31,
    April = 30,
    May = 31,
    June = 30,
    July = 31,
    August = 31,
    September = 30,
    October = 31,
    November = 30,
    December = 31
};

// инициализация по умолчанию
enum DIGITS
{
    Zero, // Zero=0 - по умолчанию
    One, // One=1
    Two,
    Three,
    Four,
    Five,
    Six, // Six = 6
    Seven,
    Eight,
    Nine // Nine = 9
};

 

4. Константные значения каких типов данных разрешается использовать в перечислениях?

В перечислениях допускается использовать константные значения следующих типов:

  • целочисленных типов (int, long int, …);
  • символьного типа char;
  • логического типа bool.

Запрещается использовать константные значения типов с плавающей запятой float, double. При попытке объявить константное значение типа double или float

...
enum DBL { x = 2.65 };
...

компилятор выдаст сообщение об ошибке

Error    1 : constant expression is not integral

 

5. Могут ли в перечислениях использоваться отрицательные значения перечислительных констант?

Да, могут. Например

enum VALUES { 
    val1 = 2,
    val2 = 'c',
    val3 = true,
    val4 = -9
};

В перечислении VALUES используется отрицательная константа

val4 = -9

 

6. Примеры объявления разных видов перечислений с различными способами начальной инициализации

Пример 1. Объявляется перечисление, реализующее месяцы года.

// перечисление, реализующее константы, которые соответствуют месяцам года
enum MONTHS { Jan = 1, Feb, Mar, Apr, May, Jun,
              Jul, Aug, Sep, Oct, Nov, Dec };

Первому месяцу года относится в соответствие константа с именем Jan. Значение константы равно 1. Следующая константа носит имя Feb, значение константы равно 2 (на 1 больше). По такому же принципу формируются константы, которые следуют после Feb. Значение каждой последующей константы больше на 1.



Пример 2. Объявляется перечисление vegetables, которое описывает овощи.

// перечисление, описывающее овощи
enum Vegetables {
    tomato, potato, carrot, cabbage, pepper, onion, radish
};

 

7. Примеры объявления и использования перечислений в программах

Пример 1. Использование перечисления в сочетании с оператором switch. Разработать программу, которая по значению константы из перечисления MONTHS выводит название соответствующего месяца.

#include <iostream>
using namespace std;

void main(void)
{
    // перечисление, реализующее константы, которые соответствуют месяцам года
    enum MONTHS { Jan = 1, Feb, Mar, Apr, May, Jun,
        Jul, Aug, Sep, Oct, Nov, Dec };

    // переменная mn типа перечисление MONTHS
    MONTHS mn;

    // присвоить значение переменной mn
    mn = Mar; // mn = 3

    // использование mn в операторе switch
    // по значению mn вывести название соответствующего месяца
    switch (mn)
    {
        case Jan: cout << "January" << endl; break;
        case Feb: cout << "February" << endl; break;
        case Mar: cout << "March" << endl; break;
        case Apr: cout << "April" << endl; break;
        case May: cout << "May" << endl; break;
        case Jun: cout << "June" << endl; break;
        case Jul: cout << "July" << endl; break;
        case Aug: cout << "August" << endl; break;
        case Sep: cout << "September" << endl; break;
        case Oct: cout << "October" << endl; break;
        case Nov: cout << "November" << endl; break;
        case Dec: cout << "December" << endl; break;
    }
}

Если попробовать вывести значение mn, то будет выводиться его целочисленное цифровое значение. Например, в коде

mn = Oct;
cout << mn; // 10

будет выводиться число 10. Идентификатор ‘Oct’ выводиться не будет.

Пример 2. Использование перечислений с оператором if. Реализация перечисления, которое описывает времена года. В программе по значению переменной типа перечисление выводится название соответствующего времени года.

#include <iostream>
using namespace std;

void main()
{
    // перечисление, реализующие времена года
    enum SEASON {
        winter, spring, summer, autumn
    };

    int i;
    SEASON sz;

    sz = spring;

    // по значению sz вывести название соответствующего времени года
    if (sz == winter)
        cout << "Winter" << endl;
    if (sz == spring)
        cout << "Spring" << endl;
    if (sz == summer)
        cout << "Summer" << endl;
    if (sz == autumn)
        cout << "Autumn" << endl;
}

 

8. Какая область видимости константы, объявленной в перечислении?

Константа, объявленная в перечислении, имеет область видимости в пределах скобок, в которых объявляется шаблон (тип) перечисления.

Например.

Дано перечисление NUMBERS, в котором объявлены 3 константы с именами num1, num2, num3. Если в этом же блоке операторных скобок { } объявить переменную с именем num2

...

{
    // область видимости имен num1, num2, num3
    enum NUMBERS
    {
        num1 = 15,
        num2 = 77,
        num3 = -1232
    };

    // попытка объявить имя num2
    int num2 = 122; // ошибка!!!
}

то компилятор выдаст ошибку

Error: 'num2' : redefinition; previous definition was 'enumerator'

 

9. Объявление типа перечисления с использованием средства typedef. Общая форма. Пример

Перечисление можно также объявлять с использованием ключевого слова typedef. В этом случае общая форма такого объявления следующая

typedef enum TypeName {
    // перечень констант и константных значений
    // ...
};

здесь TypeName – имя нового типа перечисления, которое создается.

Пример. С помощью ключевого слова typedef объявляется тип TDAYS, который есть перечислением. Затем объявляется переменная типа TDAYS.

// объявить новый тип TDAYS, который есть тип-перечисление
typedef enum TDAYS {
    Sun = 1, Mon, Tue, Wed, Thu, Fri, Sat
};

// объявить переменную типа TDAYS
TDAYS td;

// присвоить переменной td значение из набора типа TDAYS
td = TDAYS::Sun;

Источник