Объявления перечислений C

Перечисление состоит из набора именованных целочисленных констант. Объявление типа перечисления задает имя необязательного тега перечисления. Кроме того, оно определяет набор именованных целочисленных идентификаторов (называются набором перечисления, константами перечислителя, перечислителями или элементами). Переменная с типом перечисления хранит одно из значений набора перечисления, определенного этим типом.

Переменные типа enum можно использовать в выражениях индексации и в качестве операндов всех арифметических операторов и операторов отношения. Перечисления являются альтернативой директиве препроцессора #define с тем преимуществом, что можно создать значения, подчиняющиеся обычным правилам области.

В ANSI C выражения, определяющие значение константы перечислителя, всегда имеют тип int . Это значит, что хранилище, связанное с переменной перечисления, — это хранилище, необходимое для одного значения int . Константу перечисления или значение перечисляемого типа можно использовать как целочисленное выражение в любом месте, допустимом в языке C.

Синтаксис

enum-specifier:
enumidentifieropt{enumerator-list}
enum identifier

enumerator-list:
enumerator
enumerator-list , enumerator

enumerator:
enumeration-constant
enumeration-constant = constant-expression

enumeration-constant:
identifier

Необязательный параметр identifier задает имя типа перечисления, который определен с помощью enumerator-list . Этот идентификатор часто называется тегом перечисления, определенным списком. Описатель типа объявляет, что identifier является тегом для перечисления, определенного нетерминальным параметром enumerator-list , как показано ниже.

enum identifier
{
    // enumerator-list
}

enumerator-list определяет элементы набора перечисления.

Если объявление тега является видимым, все последующие объявления, в которых используется этот тег, но отсутствует enumerator-list , обозначают ранее объявленный перечисляемый тип. Тег должен ссылаться на определенный тип перечисления, и этот тип перечисления должен находиться в текущей области. Поскольку тип перечисления определен в другом месте, enumerator-list не отображается в этом объявлении. В объявлениях типов, производных от перечислений, и объявлениях typedef для типов перечислений тег перечисления может использоваться до определения типа перечисления.

Каждый параметр enumeration-constant в enumerator-list присваивает имя значению набора перечисления. По умолчанию первый параметр enumeration-constant связан со значением 0. Следующий параметр enumeration-constant в списке связывается со значением ( constant-expression + 1), если явно не указано другое значение. Имя параметра enumeration-constant эквивалентно его значению.

С помощью параметра enumeration-constant = constant-expression можно переопределить установленную по умолчанию последовательность значений. Таким образом, если enumeration-constant = constant-expression отображается в enumerator-list , параметр enumeration-constant связывается со значением, заданным constant-expression . Параметр constant-expression должен иметь тип int и может быть отрицательным.

К членам набора перечисления применяются следующие правила.

  • Набор перечисления может содержать повторяющиеся постоянные значения. Например, значение 0 можно связать с двумя разными идентификаторами, такими как элементы с именами null и zero, в одном и том же наборе.

  • Идентификаторы в списке перечисления должны отличаться от других идентификаторов в той же области с той же видимостью. К ним относятся обычные имена переменных и идентификаторы в других списках перечисления.

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

Примеры

В следующих примерах показаны объявления перечисления.

enum DAY            /* Defines an enumeration type    */
{
    saturday,       /* Names day and declares a       */
    sunday = 0,     /* variable named workday with    */
    monday,         /* that type                      */
    tuesday,
    wednesday,      /* wednesday is associated with 3 */
    thursday,
    friday
} workday;

Значение 0 связано с saturday по умолчанию. Для идентификатора sunday явно задано значение 0. Оставшимся идентификаторам по умолчанию присваиваются значения от 1 до 5.

В этом примере значение из набора DAY присваивается переменной today.

enum DAY today = wednesday;

Имя константы перечисления используется для присвоения значения. Поскольку тип перечисления DAY был объявлен ранее, необходим только тег перечисления DAY.

Чтобы явно присвоить целочисленное значение переменной перечисляемого типа данных, используйте следующее приведение типа.

workday = ( enum DAY ) ( day_value - 1 );

Это приведение рекомендовано к использованию в С, но не является обязательным.

enum BOOLEAN  /* Declares an enumeration data type called BOOLEAN */
{
    false,     /* false = 0, true = 1 */
    true
};

enum BOOLEAN end_flag, match_flag; /* Two variables of type BOOLEAN */

Это объявление также можно указать как

enum BOOLEAN { false, true } end_flag, match_flag;

или как

enum BOOLEAN { false, true } end_flag;
enum BOOLEAN match_flag;

Пример, в котором используются эти переменные, может выглядеть следующим образом.

if ( match_flag == false )
    {
     .
     .   /* statement */
     .
    }
    end_flag = true;

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

enum { yes, no } response;

См. также

Перечисления