Что такое enum в си
Перейти к содержимому

Что такое enum в си

  • автор:

Перечисляемый тип

В этой программе объявлено перечисление с именем Gender. Переменная типа enum Gender может принимать теперь только два значения – это MALE И FEMALE.

По умолчанию, первое поле структуры принимает численное значение 0, следующее 1, следующее 2 и т.д. Можно задать нулевое значение явно:

#include #include enum Token < SYMBOL, //0 NUMBER, //1 EXPRESSION = 0, //0 OPERATOR, //1 UNDEFINED //2 >; void main()

Будут выведены значения 0 1 0 1 2. То есть, значение SYMBOL равно значению EXPRESSION, а NUMBER равно OPERATOR. Если мы изменим программу и напишем

enum Token < SYMBOL, //0 NUMBER, //1 EXPRESSION = 10, //10 OPERATOR, //11 UNDEFINED //12 >;

То SYMBOL будет равно значению 0, NUMBER равно 1, EXPRESSION равно 10, OPERATOR равно 11, UNDEFINED равно 12.

Принято писать имена полей перечисления, как и константы, заглавными буквами. Так как поля перечисления целого типа, то они могут быть использованы в операторе switch.

Заметьте, что мы не можем присвоить переменной типа Token просто численное значение. Переменная является сущностью типа Token и принимает только значения полей перечисления. Тем не менее, переменной числу можно присвоить значение поля перечисления.

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

#include #include #include static char *ErrorNames[] = < "Index Out Of Bounds", "Stack Overflow", "Stack Underflow", "Out of Memory" >; enum Errors < INDEX_OUT_OF_BOUNDS = 1, STACK_OVERFLOW, STACK_UNDERFLOW, OUT_OF_MEMORY >; void main() < //ошибка случилась printf(ErrorNames[INDEX_OUT_OF_BOUNDS-1]); exit(INDEX_OUT_OF_BOUNDS); >

Так как поля принимают численные значения, то они могут использоваться в качестве индекса массива строк. Команда exit(N) должна получать код ошибки, отличный от нуля, потому что 0 — это плановое завершение без ошибки. Именно поэтому первое поле перечисления равно единице.

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

typedef enum enumName < FIELD1, FIELD2 >Name;
typedef enum Bool < FALSE, TRUE >Bool;

ru-Cyrl 18- tutorial Sypachev S.S. 1989-04-14 sypachev_s_s@mail.ru Stepan Sypachev students

email

Всё ещё не понятно? – пиши вопросы на ящик

Тип данных enum (или перечисление) в языке Си.

Тип данных enum (или перечисление) применяется чтобы дать осмысленные имена привязанные к целым числам. 1) По умолчанию элементы перечисления нумеруются с нуля и каждый следующий элемент на единицу больше предыдущего.

 enum ; // Анонимное перечисление NONE = 0, CHAR = 1, INT = 2 

2) Если задать элементу перечисления явное значение (целочисленное), то следующие элементы будут увеличиваться на единицу.

 enum ; // NONE = 2, CHAR = 3, INT = 4 printf("%d ", CHAR); // Выведет 3 

3) Элементы перечисления могут иметь отрицательные значения.

 enum ; // NONE = -3, CHAR = -2, INT = -1 

4) Элементы перечисления могут иметь одинаковые целочисленные значения и их значения могут идти не по порядку (при явной инициализации элементов).

 enum ; // NONE = 3, CHAR = 4, INT = 2, FLOAT = 3, DOUBLE = 4 

5) Перечисление может иметь имя и тогда можно создавать элементы перечисления.

 enum TYPE; // NONE = 0, CHAR = 1, INT = 2 enum TYPE a = CHAR; // a = 3 

6) Можно сразу создать элемент перечисления указав имя (имена) после фигурных скобок.

 enum TYPEtype_sample; // NONE = 0, CHAR = 1, INT = 2, type_sample = 0 type_sample = CHAR; // type_sample = 3 printf("%d ", type_sample); // Выведет 3 

Понравилась страница?
Добавить в закладки
Или поделиться!

Что такое enum в си

Перечисления (enum) представляют еще один способ определения своих типов. Их отличительной особенностью является то, что они содержат набор числовых констант. Перечисление имеет следующую форму:

enum class имя_перечисления < константа_1, константа_2, . константа_N>;

После ключевых enum class идет название перечисления, и затем в фигруных скобках перечисляются через запятую константы перечисления.

Определим простейшее перечисление:

enum class Day

В данном случае перечисление называется Day и представляет дни недели. В фигурных скобках заключены все дни недели. Фактически они представляют числовые константы.

Каждой константе сопоставляется некоторое числовое значение. По умолчанию первая константа получает в качестве значения 0, а остальные увеличиваются на единицу. Так, в примере выше Monday будет иметь значение 0, Tuesday — 1 и так далее. Таким образом, последняя константа — Sunday будет равна 6.

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

Day today ; // или так //Day today = Day::Thursday;

В данном случае определяется переменная today , которая равна Day::Thursday , то есть четвертой константе перечисления Day.

Чтобы вывести значение переменной на консоль, можно использовать преобразование к типу целочисленному типу:

#include enum class Day ; int main() < Day today ; std::cout (today)

То есть в данном случае на консоль будет выведено Today: 3 , так как константа Thursday имеет значение 3.

Мы также можем управлять установкой значений в перечислении. Так, мы можем задать начальное значение для одной контанты, тогда у последуюших констант значение увеличивается на единицу:

enum class Day ;

В данном случае Tuesday будет равно 2, а Sunday — 7.

Можно назначить каждой константе индивидуальное значение или сочетать этот подход с автоустановкой:

enum class Day ;

В данном случае Saturday будет равно 7, а Sunday — 1.

Можно даже назначать двум константам одно и то же значение:

enum class Day ;

Здесь константы Monday и Mon имеют одно и то же значение.

Можно присвоить константам значение уже имеющихся констант:

enum class Day ;

Стоит учитывать, что константы перечисления должны представлять целочисленные константы. Однако мы можем выбрать другой целочисленный тип, например, char :

enum class Operation: char ;

Если мы захотим вывести значения этих констант на консоль в виде символов, то необходимо преобразовать их к типу char :

#include enum class Operation: char ; int main() < std::cout (Operation::Add) (Operation::Subtract) (Operation::Multiply)

Применение перечислений

Перечисления удобны, когда необходимо хранить ограниченный набор состояний и в зависимости от текущего состояния выполнять некоторые действия. Например:

#include enum class Operation ; void calculate(int n1, int n2, Operation op) < switch (op) < case Operation::Add: std::cout > int main() < calculate(10, 6, Operation::Add); // 16 calculate(10, 6, Operation::Subtract); // 4 calculate(10, 6, Operation::Multiply); // 60 >

В данном случае все арифметические операции хранятся в перечислении Operation. В функции calculate зависимости от значения третьего параметра — применяемой операции выполняются определенные действия с двумя первыми параметрами.

Подключение констант перечисления

При обращении к контантам перечисления по умолчанию необходимо указывать название перечисления, например, Day::Monday . Но начиная со стандарта C++20 мы можем подключить константы перечисления в текущий контекст с помощью оператора using .

using enum Day;

И в дальнейшем использовать только имя констант:

#include enum class Day ; using enum Day; // подключаем константы перечисления в текущую область видимости int main() < Day today ; // используем только имя константы // или так //Day today = Thursday; std::cout (today) << std::endl; // 3 // выводим значение констаты Sunday std::cout (Sunday) 

Также мы можем подключить только одну константу:

using Day::Monday; // подключаем только Monday . Day today ;

В данном случае подключаем только константу Day::Monday . Для обращения к дргуим константам по прежднему необходимо использовать имя перечисления.

Поскольку такая возможность добавлена лишь начиная со стандарта С++20, то при компиляции с g++ или clang++ добавляется соответствующий флаг - -std=c++20

Перечисления в С-стиле

Стоит отметить, что раньше в С++ использовалась другая форма перечислений, которые пришли из языка С и определяются без ключевого слова class :

#include enum Day ; int main() < Day today = Tuesday; std::cout 

Такие перечисления еще называют unscoped (то есть не ограниченные ни какой областью видимостью). Естественно такие перечисления можно встретить в старых программах. Однако в виду того, что они потенциально могут привести к большему количеству ошибок, то в настоящее время такая форма все меньше и меньше используется.

Что такое enum в си

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

enum название_перечисление < константа1, константа2, . константаN >;

После слова enum идет название перечисления, затем в фигурных скобках перечисляются константы перечисления.

Определим и используем простейшее перечисление:

#include enum operation // арифметическая операция < ADD, // сложение SUBTRACT, // вычитание MULTIPLY // умножение >; int main(void) < enum operation op; // определяем переменную перечисления op = ADD; // присваиваем ей одну из констант перечисления printf("Operation: %d\n", op); return 0; >

Здесь определено перечисление, которое называется operation и которое условно представляет математическую операцию. Оно определяет три константы: ADD, SUBTRACT и MULTIPLY.

В функции main определяем переменную перечисления:

enum operation op

Этой переменной можно присвоить одну из констант перечисления. В данном случае присваиваем константу ADD :

op = ADD;

Далее мы можем использовать эту константу. В данном случае просто выводим ее значение на консоль как число. И в реальности каждой константе будет присваиваться числовое значение: первой константе - число 0, второй константе - число 1, третей - 2 и так далее. Поэтому здесь консольный вывод будет следующим:

Operation: 0

Значение константы также можно присвоить числовой переменной:

enum operation op = MULTIPLY; int opCode = op; printf("Operation Code: %d\n", opCode); // Operation Code: 2

Также можно явным образом присвоить константам числовые значения, если нам не устраивают значения по умолчанию. Можно указать значение для первой константы, тогда все последующие будут получть значение на единицу больше:

enum operation < ADD = 5, SUBTRACT, // 6 MULTIPLY // 7 >;

Можно присвоить всем уникальные значения:

enum operation < ADD = 1, SUBTRACT = 2, MULTIPLY = 4 >;

Применение перечислений

Нередко константы перечисления выступают в качестве набора состояний, и в зависимости от состояния программа выполняет ту или иную логику. Например:

#include enum operation // арифметическая операция < ADD = 1, // сложение SUBTRACT = 2, // вычитание MULTIPLY = 4 // умножение >; int calculate(int x, int y, enum operation op) < switch(op) < case ADD: return x + y; case SUBTRACT: return x - y; case MULTIPLY: return x * y; default: return 0; >> int main(void) < enum operation op = MULTIPLY; int result = calculate(4, 3, op); printf("Result: %d\n", result); // Result: 12 result = calculate(4, 3, ADD); printf("Result: %d\n", result); // Result: 7 result = calculate(4, 3, SUBTRACT); printf("Result: %d\n", result); // Result: 1 return 0; >

Здесь определена функция calculate() , которая выполняет арифметическую операцию. Первая два параметра функции представляют два числа, над которыми выполняется операция. А третий параметр - значение перечисления operation представляет тип операции. В самой функции в зависимости от третьего параметра выполняем ту или иную операцию и возвращаем ее результат.

В функции main три раза вызываем функцию calculate с одиними и теми числами, но разными типами операций.

Конечно, мы могли бы обоитись и без перечислений, используя обычные числа. Но, во-первых, перечисления представляют для своих констант описательные имена, которые часто говорят сами за себя, например, ADD(сложение). Во-вторых, в случаем с перечислением мы имеем дело с ограниченным набором констант, которыми проще управлять, нежели разрознеными числами.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *