Перечисления (enum) используются в C для создания констант. Припустимо треба оголосити константи для музичних нот і кожну форматувати відповідним порядковим номером. Можно воспользоваться уже знакомым нам способом:
Таке оголошення займає багато рядків коду і не зовсім зручно. Используя перечисление, можно определить эти константы иным способом. Синтаксис enum похож на синтаксис структур: ключевое слово – дескриптор – елементи в фігурних дужках через кому:
Это полная форма – с дескриптором (именем перечисления). Как и в случае со структурами, имя перечисления можно не использовать:
В первом случае – ми зможемо створювати змінні типу перерахуванняnotes. Во втором случае – нет.
Зверніть увагу, что значение 1 было присвоено только первому элементу перечисления. По умолчанию первому элементу в фигурных скобках присваиваются значение 0, второму на единицу больше (1), третьему на единицу больше второго (2) і т.д. Но если явно задать значение, как в примере, то увеличение на единицу начнется с этого числа. Покажем на экран значения некоторых элементов перечисления.
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <iostream> using namespace std; enum notes{ DO = 1, RE, MI, FA, SOL, LA, SI }; int main() { setlocale(LC_ALL, "rus"); cout << DO << ' ' << RE << ' ' << SOL << endl; return 0; } |
Хоть мы и не присваивали явно значения RE і SOL– они хранят правильные порядковые номера нот.
Имена перечислителей (элементов перечисления) должны быть уникальными. Значения же могут совпадать:
1 | enum champions{ KLICHKO_VITALIY = 1, KLICHKO_VLADIMIR = 1, CHISORA, ADAMEK }; |
Значение 1 зберігатимутьKLICHKO_VITALIY іKLICHKO_VLADIMIR. 2 запишется вCHISORA, 3 – вADAMEK . В элементы перечисления могут быть записаны только целые числа. Изменить ниже в программе значения, которые присвоены элементам в фигурных скобках нельзя. Если создается переменная типа перечисления – она может принять значение только одного из своих элементов:
На картинке видно, что записать число в переменную типа champions возможности нет. Можно записать только именованную константу, которая объявлена во время определения enum.
Для закрепления рассмотрим пример. У ньому створимо перерахуванняlevelsName. Оно будет содержать шесть элементов – “названия” этажей. користувачеві запропонуємо“покататься” на лифте.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #include <iostream> using namespace std; enum levelsName { parking, bank, insurance, exchange, showroom, Restaurant }; int main() { setlocale(LC_ALL, "rus"); int floor = parking; // выбор пользователя - номер этажа int exitOrNot = 1; // выйти или нет while (exitOrNot == 1) { cout << "Номер этажа (0,1,2,3,4,5): "; cin >> floor; switch (floor) { case(parking) : cout << "\a\a\aВы в паркинге!\n\n"; break; case(bank) : cout << "\a\a\aПервый этаж!"; cout << "\nЗдесь находится Креди Агриколь Банк.\n\n"; break; case(insurance) : cout << "\a\a\aВторой этаж!"; cout << "\nСтраховая компания UNICA.\n\n"; break; case(exchange) : cout << "\a\a\aТретий этаж!"; cout << "\nФондовая биржа.\n\n"; break; case(showroom) : cout << "\a\a\aЧетвёртый этаж!"; cout << "\nВыставочный зал и зал для презентаций.\n\n"; break; case(Restaurant) : cout << "\a\a\aПятый этаж!"; cout << "\nРесторан Sky.\n\n"; break; default: cout << "\a\a\aОшибка!\n\n"; } cout << "Выйти из лифта - нажмите 0.\n"; cout << "Выбрать другой этаж - нажмите 1: "; do { cin >> exitOrNot; } while (exitOrNot != 0 && exitOrNot != 1); cout << endl; } return 0; } |
Объявляем целочисленную переменную floor в строке 10 і инициализируем її іменованою константоюparking. Так floor примет значение 0. В рядку 13 входим в цикл while. Поки користувач не введе в зміннуexitOrNot значение 0, программа будет ему предлагать “кататься на лифте” – выбрать номер этажа.
После каждого выбора этажа звучит сигнал (три коротких гудка) і на екран виводиться номер поверху і інформація про те, что на нём размещено. Это реализовано оператором вибору switch. його блокиcase перебирают элементы перечисления. То есть пользователь вводит целое число, аcase ищет, какому из элементов перечисления оно соответствует.
Наприклад, если введено 5 – це відповідає значенню елементаRestaurant – на екран виводиться відповідне повідомлення.
Результат:
Подивіться коротке відео про перерахування C ++.
нормальні приклади, а статтю не читав.
Я сформулюю, а ти поправ ласка, якщо до статті я розійдуся в чомусь.
1) магічні числа – це погано, щоб позбутися від них використовують константи.
2) константи – це добре, але константи сильно пов'язані один з одним.
Приклад: в програмі у нас є юніт. Юніт може бути магом, гоблином або ельфом. Одним з варіантів реалізації цього могло бути щось таке:
Const INT Mag = 1;
Const INT Гоблін = 2;
Const INT Elf = 3;
структура Unit {
ім'я рядка;
INT UNIT_TYPE;
};
очевидно, це погано, тому що:
2.1) константи Mag, гоблін, Elf доступні всім, т.е. засмічують простір імен;
2.2) константи можуть бути випадково використані в неправильному контексті, адже вони не згруповані, т.е. нічим не відрізняються від інших констант;
2.3) полю unit_type можна привласнити неправильне значення (компілятор повідомить нам про помилку) :
unit.unit_type = -123;
2.4) нам треба придумувати самим значення констант і стежити щоб вони не повторювалися.
Всі ці проблему еротично вирішує enum:
перелічувальний UnitType { магнітний, гоблін, ельф };
структура Unit {
Тип UNIT_TYPE;
ім'я рядка;
};
звернутися до констант ми можемо як безпосередньо (магнітний) так і по імені перерахування (UNITTYPE::магнітний). Другий варіант позначає явно контекст, але начебто з'явився в С ++ 11 (раніше його підтримувала більшість компіляторів, але стандарту ніби як воно не відповідало).
unit.unit_type = 123;
завершиться помилкою на етапі компіляції (т.е. дуже рано). А якщо ви юзаєте сучасну IDE – то ще раніше (середовище розробки підкреслить помилку).
Ну і значення їм присвоєні автоматично, стежити за цим не треба.
Код можна зробити трохи красивіше:
структура Unit {
Тип іпіт {магнітний, гоблін, ельф} тип;
ім'я рядка;
};
Це може бути краще, т.к. видно, що Unit і Type нерозривно пов'язані (раніше ми кодували це в імені UnitType). Кодувати щось в імені не дуже добре, наприклад якби Unit перейменували б в Item – то нам довелося б перейменовувати ItemType, або зв'язок стала б не очевидна.
блок::тип::Mag лаконічно задає контекст, в якому може використовуватися константа.
Ну а ще unum активно використовується з шаблонами, але це зовсім інша тема. Ти її розкриєш? )
Мій варіант вирішення завдання з прикладу:
попередньо клас =”тільки:C ++ декодуванням:true ”
#include
using namespace std;
int main()
{
setlocale(LC_ALL, “rus”);
перерахувань lewels {undParking = -1, oneFloor = 1, secondFloor = 2, ресторан = 3, Пентхаус = 4};
INT ліфт = 0;
int exit = 1;
cout <<"Вы зашли в здание и сейчас находитесь на " << oneFloor << " этаже \n";
do
{
cout <> ліфт;
switch (ліфт)
{
case(undParking):
cout << "Вы попали в подземную автостоянку \n";
break;
case(oneFloor):
cout << "Вы на первом этаже \n";
cout <> exit;
if (exit == 0)
{
cout << "Вы вышли из здания \n";
}
break;
case(другий поверх):
cout << "Вы на втором этаже \n";
break;
case(Restaurant):
cout << "Вы в ресторане \n";
break;
case(пентхауз):
cout << "Вы в пентхаусе \n";
break;
default:
cout << "Нет такого этажа \n";
}
} while (exit == 1);
return 0;
}
/заздалегідь
Перерахування в мові C ++ прямо успадковують поведінка перерахувань мови C, за винятком того, що перераховується тип в C ++ - справжній тип, і ключове слово
Цитата з опису мов C і C ++:
> У версії С89 визначено 32 ключових слова.
> …
> enum - Призначений для користувача тип даних “перераховується тип”
> …
> У мові C ++ містяться всі ключові слова, визначені в версії С89, а також такі.
І де тут відмінність?
Якщо для кожного випадку перерахування задано значення (відоме як значення "raw"), це значення може бути рядком, символом або значенням будь-якого цілого числа або типу з плаваючою комою.