Что такое перечисление в программировании

Перечисления (C++)

Перечисление — это пользовательский тип, состоящий из набора целочисленных констант, называемых перечислителями.

В этой статье рассматривается тип языка C++ Standard в формате ISO enum и тип enum с областью действия (или строго типизированный), который появился в C++ 11. Сведения об открытых классах enum или закрытых типах классов enum в c++/CLI и c++/CX см. в разделе Класс Enum.

Синтаксис

Параметры

identifier
Имя типа, присваиваемое перечислению.

type
Базовый тип перечислителей; все перечислители имеют один базовый тип. Может быть любым целочисленным типом.

Область перечислителя

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

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

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

Приведение правил

Неограниченные константы перечисления могут быть неявно преобразованы в, но никогда не может быть неявно преобразовано int int в значение enum. В следующем примере показано, что пройдет при попытке присвоить переменной hand значение, не относящееся к типу Suit :

Для преобразования int в перечислитель с областью или вне области действия требуется приведение. Однако неограниченный перечислитель можно преобразовать в целочисленное значение без приведения.

Использование подобных неявных преобразований может приводить к непредвиденным побочным эффектам. Чтобы избежать ошибок программирования, связанных с неограниченными перечислениями, значения ограниченных перечислений являются строго типизированными. Ограниченные перечислители должны уточняться именем типа перечисления (идентификатором); они не могут быть неявно преобразованы, как показано в следующем примере:

Обратите внимание, что в строке hand = account_num; по-прежнему содержится ошибка, которая происходит при использовании неограниченных перечислений, как показано выше. Эта ошибка устраняется с помощью явного приведения. Однако при использовании ограниченных перечислений попытка преобразования в следующем операторе — account_num = Suit::Hearts; — больше не будет разрешена без явного приведения.

Перечисления без перечислителей

Visual Studio 2017 версии 15,3 и более поздних версий (доступно в и более поздних версиях): путем определения перечисления (regular или с ограниченной областью) с явным базовым типом и без перечислителей, вы можете использовать новый целочисленный тип, который не имеет неявного преобразования в любой другой тип. Используя этот тип вместо встроенного базового типа, можно исключить потенциальные ошибки для незначительных ошибок, вызванных случайными неявными преобразованиями.

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

Источник

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

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

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

Синтаксис

enum-specifier :
enum identifier enum < enumerator-list >
enum identifier

enumerator-list :
enumerator
enumerator-list , enumerator

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

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

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

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

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

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

Примеры

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

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

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

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

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

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

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

Источник

Перечисления в C#: как правильно использовать enum

В C# есть много крутых инструментов, которые позволяют улучшить любой код. Один из них — enum. Давайте разберёмся, что это и как с ним работать.

Списки перечисления (или enum) сокращают код и улучшают его читаемость. В этой статье мы создадим enum и научимся применять его эффективно.

Что такое enum в C#

Это список однотипных значений: цветов, состояний, способов выравнивания и так далее. Например, в C# существует встроенный список цветов:

То есть нам не нужно вручную вводить код цвета — вместо этого мы просто выбираем значение из заранее составленного списка.

В самом enum тоже не хранится код цвета. Цифра 9 на примере выше — это индекс элемента в списке. Логика изменения цвета в нашем случае примерно такая:

Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.

Как создать enum в C#

Создайте отдельный файл и назовите его так, чтобы понять, какой это список. Например, Direction.cs:

После объявления нового enum он используется как тип данных:

Вы можете указать и какие-то собственные значения для элементов. Например, коды ответа веб-сервера:

По умолчанию тип значения — int, но он изменяется на любой другой целочисленный тип:

Как использовать enum в C#

Самый простой пример — конструкции if и switch.

Вот результат работы такой программы:

Также вы можете использовать enum вместе с полиморфизмом.

Таким образом вы получите код, который очень быстро читается. И теперь не нужно думать, какой метод использовать, — благодаря полиморфизму всё выглядит почти как человеческая речь: set item type — Food (указать тип предмета — Еда).

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

Этот метод возвращает три сообщения в зависимости от ситуации:

Конечно, допустимо куда больше вариантов: от ошибки базы данных до превышения времени ожидания.

Как enum помогает улучшить читаемость

Представим, что у нас есть класс Item со следующими полями:

Все эти значения передаются объекту через конструктор, поэтому инициализация выглядит так:

Без enum со временем вы забудете, за что отвечает третий аргумент, и вам придётся каждый раз проверять реализацию класса, чтобы освежить память. Или вы добавите новые типы предметов, из-за чего таких аргументов ( isArmor, isPotion) станет ещё больше:

Избежать таких неприятных моментов как раз и помогает enum: создайте перечисление ItemType и передавайте в конструктор его.

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

Источник

9.2 – Перечислимые типы данных

C++ содержит довольно много встроенных типов данных. Но этих типов бывает не всегда достаточно для того, что мы хотим сделать. Итак, C++ содержит возможности, позволяющие программистам создавать свои собственные типы данных. Эти типы данных называются пользовательскими типами данных.

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

Обратите внимание, что каждый перечислитель отделяется запятой, а всё перечисление заканчивается точкой с запятой.

Именование перечислений и перечислителей

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

Перечислителям должны быть даны имена, и они обычно используют тот же стиль именования, что и константные переменные. Иногда перечислителям даются имена ПОЛНОСТЬЮ_ЗАГЛАВНЫМИ_БУКВАМИ, но делать это не рекомендуется, поскольку это может привести к путанице с именами макросов препроцессора.

Область видимости перечислителя

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

Значения перечислителей

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

Приведенная выше инструкция с cout выводит значение 4.

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

Обратите внимание, что в этом случае animal_horse и animal_giraffe имеют одинаковые значения. Когда это происходит, перечислители становятся неразличимыми – по сути, animal_horse и animal_giraffe взаимозаменяемы. Хотя C++ позволяет это, обычно следует избегать присвоения одного и того же значения двум перечислителям в одном перечислении.

Лучшая практика

Не назначайте перечислителям конкретные значения.

Лучшая практика

Не присваивайте одно и то же значение двум перечислителям в одном перечислении, если в этом нет веской причины.

Вычисление перечислимого значения и ввод/вывод

Это дает следующий результат:

Компилятор не будет неявно преобразовывать целочисленное значение int в перечислимое значение. Следующее приведет к ошибке компиляции:

Однако вы можете заставить его сделать это с помощью static_cast :

Компилятор также не позволит вам выполнить ввод перечисления с помощью std::cin :

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

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

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

Печать перечислителей

Как вы видели выше, попытка напечатать перечислимое значение с помощью std::cout приводит к печати целочисленного значения перечислителя. Так как же распечатать сам перечислитель в виде текста? Один из способов сделать это – написать функцию и использовать оператор if или switch :

Выделение памяти для переменных типа enum и предварительное объявление

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

Чем полезны перечислители?

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

Например, старые функции для представления кодов ошибок, когда что-то пошло не так внутри функции, иногда возвращают вызывающему целые числа. Обычно для обозначения различных возможных кодов ошибок используются небольшие отрицательные числа. Например:

Однако использование подобных магических чисел не очень наглядно. Альтернативный метод – использование перечислимого типа:

Это намного легче читать и понимать, чем использовать магические числа в качестве возвращаемого значения. Кроме того, вызывающий может проверить возвращаемое значение функции по соответствующему перечислителю, что легче понять, чем проверять возвращаемый результат на совпадение с определенным целочисленным значением.

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

Или, в качестве альтернативы, если бы вы писали функцию для сортировки кучи значений:

Небольшой тест

Вопрос 1

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

Вопрос 2

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

Вопрос 3

Верно или нет. Перечислителями могут быть:

Источник

Перечисления (enum) на C++

В этой статье вы научитесь работать с перечислением (enum). Кроме того, вы узнаете, где перечисления обычно используются в программировании на C++.

Что такое перечисления в C++?

Перечисления в C++ – это определяемый пользователем тип данных, состоящий из целочисленных констант. Для определения перечисления используется ключевое слово enum.

Здесь название перечисления – season.

По умолчанию весна – 0, лето – 1 и так далее. Вы можете изменить значение по умолчанию для элемента перечисления во время объявления (при необходимости).

Объявление типа enum

Когда вы создаете тип enum, создается только схема для переменной. Вот как вы можете создавать переменные типа enum.

Здесь создается проверка переменной типа enum boolean.

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

Пример 1

Пример 2: изменение значения перечислений по умолчанию

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

Это потому, что размер целого числа составляет 4 байта.

Вы можете выполнить ту же задачу, используя структуры C++. Однако работа с перечислениями обеспечивает эффективность и гибкость.

Как использовать перечисления?

Есть причина, по которой все интегральные константы в приведенном выше псевдокоде имеют степень двойки.

Поскольку интегральные константы имеют степень двойки, вы можете комбинировать два или более флага одновременно без перекрытия, используя побитовое OR | operator. Это позволяет вам выбрать сразу два или более Flags. Например:

Когда на выходе получается 5, вы всегда знаете, что используются жирный шрифт и подчеркивание.

Здесь мы добавили курсив к нашему дизайну. Обратите внимание: внутри оператора if написан только код, выделенный курсивом.

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

Источник

Понравилась статья? Поделиться с друзьями:

Не пропустите наши новые статьи:

  • Что такое переустановка windows
  • Что такое переустановить программу
  • что такое переустановить виндовс с этого устройства
  • Что такое перетаскивание объекта в windows
  • Что такое переносимость программ

  • Операционные системы и программное обеспечение
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии