Перечисления в С++ (enum)

И так, что же такое перечисление или, правильней сказать, перечисляемые типы в С++?  Тема не из самых сложных. Само название —  перевод  с английского enumeration.  А перечисляются целые константы.   Простым для понимания сути вопроса будет такой пример: объявим  перечисляемый тип годовщин свадьбы.

#include <iostream> 
using namespace std;

enum  weddingAnn {chintz = 1, paper, leather, linen, wooden} year;//определяем перечисление и объявляем переменную

int main()
{
	setlocale(LC_ALL, "rus");

	cout << "Олег с Ольгой отмечают\t" << chintz << "-ю годовщину со дня свадьбы!!!";
	cout << "\n";
	cout << "Андрей с Анной отмечают\t" << paper << "-ю годовщину со дня свадьбы!!!";
	cout << "\n";
	cout << "Марк с Ириной отмечают\t" << leather << "-ю годовщину со дня свадьбы!!!";
	cout << "\n";
	cout << "Игорь с Юлией отмечают\t" << linen << "-ю годовщину со дня свадьбы!!!";
	cout << "\n";
	cout << "Олег с Аллой отмечают\t" << wooden << "-ю годовщину со дня свадьбы!!!";
	cout << "\n\n";

return 0;
}

Определяем перечисление — строка 4 . Для этого используется зарезервированное слово enum, далее даем название типу — в нашем случае weddingAnn, в фигурных скобках объявляем целочисленные константы (элементы перечисления)  {chintz = 1, paper, leather, linen, wooden}, объявляем переменную (декларатор) year    в конце ставим ;. Объявление типа  и переменной  необязательно  при определении перечисления. В нашем примере мы могли обойтись и без них — enum {chintz = 1, paper, leather, linen, wooden};, но лучше сразу показать полную версию. Вы, скорее всего, обратили внимание на то, что первому элементу chintz мы присвоили значение 1. Дело в том, что по умолчанию, при определении перечисления, первой перечисляемой константе присваивается значение 0, а для остальных на единицу больше, чем у предыдущей. Поэтому нам достаточно было присвоить значение только первой константе. Остальные значения присвоились автоматически. При выводе данных на экран , строки 10 — 18, мы указываем название годовщин свадеб, а компилятор уже обращается к элементам перечисления и предоставляет нам целое число, которое хранит этот элемент (идентификатор).

Что мы увидим в консоли:

CppStudio.com

Олег с Ольгой отмечают   1-ю годовщину со дня свадьбы!!!
Андрей с Анной отмечают  2-ю годовщину со дня свадьбы!!!
Марк с Ириной отмечают   3-ю годовщину со дня свадьбы!!!
Игорь с Юлией отмечают   4-ю годовщину со дня свадьбы!!!
Олег с Аллой отмечают    5-ю годовщину со дня свадьбы!!!

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

  • Первое, то что мы уже знаем:  всем идентификаторам (целочисленным константам) перечисления присваивается значение. По умолчанию первому – 0, остальным на единицу больше предыдущего значения. А если мы сами задаем значение — то это может быть любое целое число. При этом, ВАЖНО, имена целочисленных констант должны быть уникальны. При определении одинаковых имен компилятор выдаст ошибку. А вот значения, которые мы присваиваем  константам могут совпадать. Например:  enum year{vadim = 2, vanya = 2, sonya, yula = 0,  denis = sonya + 20,}; Когда выведем эти значения на экран, увидим 2, 2, 3, 0, 23.
  • Перечисление — это отдельный тип данных. Так типом  идентификаторов vadim, vanya, sonya и т.д. выступает тип year.
  • Значение константам можно присвоить только в фигурных скобках при определении перечисления. Изменить его ниже в коде уже нет возможности.
  • Определяя перечисление, объявление типа и переменной необязательно.
  • Переменная (декларатор) типа созданного нами  перечисления может иметь значение одной из определённой в перечислении константы.  Чтобы было понятней, если в функции main мы объявляем переменную типа перечисления, это будет выглядеть так — year child = sonya;.
  • используя перечисления, мы можем сделать наши коды программ более понятными. В первую очередь потому, что благодаря им возможно использовать в программе не «магические числа» инициализированных где-то в коде переменных, а  читаемые названия элементов перечисления. Но, как всегда, не увлекайтесь. Всего в меру.

Рассмотрим еще один код программы. Здесь мы создадим перечисление level (этаж) и предложим пользователю проехаться на виртуальном лифте по виртуальному торговому центру.

#include <iostream> 
using namespace std;

//определяем перечисление 
enum level {parking, supermarket, hardwareStores, boutiques, sportSpa, clubRestaurantBar};

int main()
{
	setlocale(LC_ALL, "rus");

	level floor = parking;//переменная типа перечисления level
	//level floor = 0; не скомпилируется
	int fl = floor;//выбор этажа пользователем	
	bool exit = true;//выбор пользователя - выйти и продолжить

	cout << "\n\t$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n";
	cout << "\tДобро пожаловать в наш торгово-развлекательный центр MALL!!!\n";
	cout << "\tПредлагаем Вам проехаться в лифте и посетить все этажи!\n\n";
	cout << "\t$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n";

	while(exit)//пока exit равен true 
	{
		cout << "\nНажмите кнопку с номером этажа (от 0 до 5): ";
		cin >> fl;

		switch(fl)
		{
		case(parking): 
		cout << "\aВы спустились в паркинг!!!" << endl;
		break;

		case(supermarket): 
		cout << "\aВы на первом этаже!";
		cout << "\nЗдесь вы можете посетить наш супермаркет и купить продукты и товары для дома.\n\n";
		break;

		case(hardwareStores): 
		cout << "\aВы на втором этаже!"; 
		cout << "\nЗдесь расположились магазины бытовой техники, IT  и мобильных телефонов.\n\n";
		break;

		case(boutiques): 
		cout << "\aВы на третьем этаже!";
		cout << "\nЗдесь вас ждет незабываемый шопинг! Одежда, обувь, магазины косметики.\n\n";
		break;

		case(sportSpa): 
		cout << "\aВы на четвертом этаже!";
		cout << "\nЗдесь вы можете посетить бассейн, каток, спортзалы, spa-салон!\n\n";
		break;

		case(clubRestaurantBar): 
		cout << "\aВы на пятом этаже!";
		cout << "\nТут вы можете посетить ночной клуб, бар и ресторан!\n\n";
		break;

		default: cout << "\a\a\aОшибка! У нас только 5 этажей!\n\n"; 	
		}

		cout << "Если хотите выйти на этом этаже, нажмите 0.\n";
		cout << "Продолжить увлекательную поездку - нажмите 1: ";
		cin >> exit;
	}	
return 0;
}

Строка 5 — определяем перечисление level, где целочисленными константами (элементами перечисления) выступают названия этажей {parking, supermarket, hardwareStores, boutiques, sportSpa, clubRestaurantBar};.  Как видите, мы не присваиваем значения константам. Пусть за нас это сделает компилятор. Естественно, по умолчанию элементу parking будет присвоено  значение 0, а последнему clubRestaurantBar — значение 5. В строке 11 мы создаем переменную floor типа перечисления level, и инициализируем ее значением parking.   Потом создаем переменную fl типа int и присваиваем ей значение переменной floorстрока 13.  В строке 21 входим в цикл while в котором предлагаем пользователю выбрать номер этажа от 0 до 5. Пользователь вводит число и срабатывает switch, определённый в строках 26-58. В нём мы перебираем значения переменной fl используя названия элементов перечисления:  case(parking)://код, case(supermarket)://код и т.д., срабатывает звуковой сигнал \a и пользователю показывается информация об этаже, на который он прибыл. Далее предлагаем сделать выбор  — выйти из лифта либо переместиться на другой этаж —  строки 60-62 . Если Пользователь введёт 0  — цикл while прекратит свою работу.

Результат:

CppStudio.com
	$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

	Добро пожаловать в наш торгово-развлекательный центр MALL!!!
	Предлагаем Вам проехаться в лифте и посетить все этажи!

	$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

Нажмите кнопку с номером этажа (от 0 до 5): 1
Вы на первом этаже!
Здесь вы можете посетить наш супермаркет и купить продукты и товары для дома.

Если хотите выйти на этом этаже, нажмите 0.
Продолжить увлекательную поездку - нажмите 1: 1

Нажмите кнопку с номером этажа (от 0 до 5): 3
Вы на третьем этаже!
Здесь вас ждет незабываемый шопинг! Одежда, обувь, магазины косметики.

Если хотите выйти на этом этаже, нажмите 0.
Продолжить увлекательную поездку - нажмите 1: 0

Надеюсь, эта статья помогла вам узнать, а главное, понять перечисления. Если у вас остались вопросы по этой теме — ждем их в комментариях к данной статье. Мы вам ответим, не сомневайтесь!

Практика

К сожалению, для данной темы пока нет подходящих задач. Если у вас есть таковые на примете, отправте их по адресу: admin@cppstudio.com. Мы их опубликуем!

Автор: Marienko L.
Дата: 12.01.2014
Поделиться:

Комментарии

  1. JunoDavis

    JunoDavis

    Моя версия:

    char exit;//выбор пользователя - выйти и продолжить
    /*...*/
    do {
    		cout << "\nНажмите кнопку с номером этажа (от 0 до 5): ";
    		cin >> fl;
    
    		switch(fl)
    		{
    		/*...*/
    
    		default: cout << "\a\a\aОшибка! У нас только 5 этажей!\n\n";break; 
    		}
    				
    		cout << "Хотите продолжить?(y/n) ";
    	}  while(cin >> exit && exit == 'y');

     

  2. hopf

    Здравствуйте!

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

    Для лучшего понимания: нужно составить своего рода базу данных на сотрудников, имеется список должностей (перечисление) также ввод\вывод даты приема, з\п и личного номера сотрудника. Должность должна определяться при введении первой буквы ее названия (первый switch), а затем, после ввода остальных данных, должна выводиться введенная информация. В поле должности- ее название, а получается только значение.

    #include <iostream>
    #include <locale>
    #include <conio.h>
    
    using namespace std;
    
    struct date
    {
    	int day;
    	int month;
    	int year;
    };
    
    enum etype{ laborer, secretary, manager, accountant, executive, researcher };
    
    struct employee
    {
    	int numb;
    	float salary;
    	etype jober;
    	date Date;
    };
    
    int main()
    {
    	setlocale(LC_ALL,"russian");
    	employee job1, job2, job3;//переменные типа employee для сохранения данных о сотрудниках
    	//myLabel2, myLabel3;
    	cout << "\nВведите номер работника " ;
    	cin >> job1.numb;
    	cout << "\nпервую букву должности (l,s,m,a,e,r) ";
    	char typejob;
    	myLabel1: cin >>  typejob; //переменная для ввода должности
    	switch(typejob)
    	{
    	    case 'l': job1.jober=laborer;break;
    		case 's': job1.jober=secretary;break;
    		case 'm': job1.jober=manager;break;
    		case 'a': job1.jober=accountant;break;
    		case 'e': job1.jober=executive;break;
    		case 'r': job1.jober=researcher;break;
    		default : cout << "\nНеверно! Введите первую букву должности (l,s,m,a,e,r)";goto myLabel1;//переход на ввод должности
    	};
    	
    	switch(job1.jober)
    	{
    		case '0': "лаборант";break;
    		case secretary: "секретарь";break;
    		case manager: "управляющий";break;
    		case accountant: "бухгалтер";break;
    		case executive: "администратор";break;
    		case researcher: "исследователь";break;
    	};
    	
    	cout << "\nзарплату ";
    	cin >> job1.salary;
    	cout << "\nдату принятия на работу (разделяя enter'ом)";
    	cin >> job1.Date.day >> job1.Date.month >> job1.Date.year;
    	cout << "\nНомер сотрудника: " << job1.numb << "\nдолжность: " << job1.jober << "\nзарплата: " << job1.salary << "\nдата принятия на работу: "
    		<< job1.Date.day <<"/" << job1.Date.month << "/" << job1.Date.year << endl;
    	getch();
    	return 0;
    }
  3. Marienko L.

    Marienko L.

    Да, в типе bool  true  — это любое число ( в т.ч. и отрицательное) кроме 0. Но, дело в том, что в настоящее время в С++ оператор >> перегружен и позволяет ввести только 0 или 1. Если ввести другое число, bool exit станет true, а cin установится в состояние ошибки. Поэтому программа «сломается».

  4. afrira2008

    Подскажите пожалуйста, ведь true — это любое значение от 1 до 255. В вышеописанном коде у меня происходит следующее: если я набираю 1 — всё нормально, происходит выбор этажей, а если другую цифру (2, 4 и т.д.) то программа зацикливается. Почему? У меня установлена Code::Blocks 13.12

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.