Объявления перечислений C
Перечисление состоит из набора именованных целочисленных констант. Объявление типа перечисления задает имя необязательного тега перечисления. Кроме того, оно определяет набор именованных целочисленных идентификаторов (называются набором перечисления, константами перечислителя, перечислителями или элементами). Переменная с типом перечисления хранит одно из значений набора перечисления, определенного этим типом.
Переменные типа enum
можно использовать в выражениях индексации и в качестве операндов всех арифметических операторов и операторов отношения. Перечисления являются альтернативой директиве препроцессора #define
с тем преимуществом, что можно создать значения, подчиняющиеся обычным правилам области.
В ANSI C выражения, определяющие значение константы перечислителя, всегда имеют тип int
. Это значит, что хранилище, связанное с переменной перечисления, — это хранилище, необходимое для одного значения int
. Константу перечисления или значение перечисляемого типа можно использовать как целочисленное выражение в любом месте, допустимом в языке C.
Синтаксис
enum-specifier
:
enum
identifier
необ.{
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;