Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 83, средняя оценка - 4.76
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
#1

Диапазон перечисления enum и его размер. - C++

20.04.2009, 23:10. Просмотров 10737. Ответов 13
Метки нет (Все метки)

Объясните,пожалуйста,точный,на Ваш взгляд,смысл диапазона перечисления enum и есть ли связь размера и диапазона? Точнее:
Например,есть
C++
1
enum e1{a=3,b=9}
,тогда диапазон значений e1 будет 16(0:15),так?И потом,например,определяем внутренние элементы перечисления,и если
C++
1
2
enum e1{a=3,b=9};
e1 c=85;
,то "c" должно быть неопределено,а у меня вот при печати оно выводится правильно.Причём можно присваивать все числа до границы unsigned long int.Почему так?Вот если с плавающей точкой ввожу,то на выходе чепуха,а так как будто всё нормально.
И ещё одно-размер sizeof(e1) у меня всегда равен размеру int,но это,наверное,потому,что перечисление хранится целым числом,а имена-всего лишь как переменные в программе?То есть размер и диапазон не связаны,так?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.04.2009, 23:10
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Диапазон перечисления enum и его размер. (C++):

Размер перечисления enum - C++
Добрый день. Где-то я вычитал, что размер перечисления не всегда может быть одинаковый. Из чего вопрос, как зафиксировать размер...

Правильное применение перечисления enum - C++
Дело в том, что не пойму как работать с перечислением. Мне нужно, чтобы программа принимала данные о 3 сотрудниках ( дата найма на работу,...

Определение перечисления (enum) в другом файле - C++
Доброго времени суток! :) Вот мой вопрос: в классе A мне необходимо использовать перечисление B, но объявление и определение класса...

Передача элементов перечисления (enum) в конструктор - C++
Всем добрый день! Заметил некоторые странности при передачи элементов перечисления в конструктор. Вот пример: #include <iostream> ...

Перечисления enum. Хранение типа телефонного номера - C++
Ввести в массив структур N записей из телефонной книжки (фамилия, имя, номер телефона, тип номер (домашний, рабочий, мобильный)). Вывести...

Перечисления. Переменная не входит в диапазон - C++
Что плохого может случится, если переменной установить значения вне диапазона? #include <iostream> enum flag{x=1, y=2, z=4,...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
ISergey
Maniac
Эксперт С++
1373 / 884 / 52
Регистрация: 02.01.2009
Сообщений: 2,653
Записей в блоге: 1
21.04.2009, 00:29 #2
C++
1
2
enum e1{a=3,b=9};
e1 c=85;//у меня такое даже не скомпелит
Gravity
562 / 556 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
21.04.2009, 00:58 #3
Не совсем понимаю о каком диапазоне идет речь.
C
1
enum e1{a=3,b=9}
определяет целочисленные константы a и b, объединенные под одним типом e1, ничего более. Аналогично было бы, если записать
C
1
2
#define a 3
#define b 9
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
21.04.2009, 21:22  [ТС] #4
Цитата Сообщение от Gravity Посмотреть сообщение
Не совсем понимаю о каком диапазоне идет речь.
C
1
enum e1{a=3,b=9}
определяет целочисленные константы a и b, объединенные под одним типом e1, ничего более. Аналогично было бы, если записать
C
1
2
#define a 3
#define b 9
Стауструп. "Язык программирования С++" 4.8.Перечисления,стр 116.
Цитата Сообщение от ISergey Посмотреть сообщение
/у меня такое даже не скомпелит
А что за компилятор?У меня "gcc версия 4.2.4"
Humanitis
172 / 164 / 6
Регистрация: 12.01.2009
Сообщений: 430
21.04.2009, 22:01 #5
Цитата Сообщение от #pragma Посмотреть сообщение

enum e1{a=3,b=9};
e1 c=85;
Стандарт запрещает преобразование int в тип enum

Цитата Сообщение от #pragma Посмотреть сообщение
,тогда диапазон значений e1 будет 16(0:15),так?
Все верно,и по Страуструпу и по стандарту. Однако у каждого перечисления есть основной тип,по умолчанию он int
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
21.04.2009, 22:35  [ТС] #6
Цитата Сообщение от Humanitis Посмотреть сообщение
Стандарт запрещает преобразование int в тип enum
Вот почему-то не запрещает:у Страуструпа на этот счёт ничего не написано,сказано лишь,что "результат (неявного) преобразования не определён",компилятор почему-то тоже молчит,даже не предупреждает.Может,там опции покрутить надо?Работаю в Code::Blocks,использую только стандартную библиотеку.Правда,книжка датирована 2001 годом,но ведь компилятор-то версии из последних ..
Evg
Эксперт CАвтор FAQ
17619 / 5843 / 375
Регистрация: 30.03.2009
Сообщений: 16,118
Записей в блоге: 26
21.04.2009, 22:56 #7
Цитата Сообщение от ISergey Посмотреть сообщение
C++
1
2
enum e1{a=3,b=9};
e1 c=85;//у меня такое даже не скомпелит
Потому что ты нигде не определяешь тип e1. Определяешь только тип "enum e1", что не одно и то же. По крайней мере с точки зрения Си. Но вот на Си++ есть какие-то правила в каком-то порядке, но в данном случае "e1" будет соответсвоать "enum e1". Правильно писать "enum e1 c = 85"

Добавлено через 7 минут 7 секунд
Цитата Сообщение от Humanitis Посмотреть сообщение
Стандарт запрещает преобразование int в тип enum
Насколько я знаю, не запрещает. Хотя мои знания касаются в основном Си. Но принципиальной недопустимости такой операции на Си++ как-то с ходу не вижу.

Цитата Сообщение от Humanitis Посмотреть сообщение
Однако у каждого перечисления есть основной тип,по умолчанию он int
И ещё. Этот тип не меньше чем int. Т.е. если у тебя в enum'е все константы влезают в 32 бита, то базовым типом будет int (или unsigned int, с ходу не скажу). Если константы бОльшего размера, то наименьший тип, имеющий размер 8. Для 32-разрядных машин это long long, для 64-разрядных - long (либо соответсвующие unsigned)

Проверить, что именно мы имеем в данном случае, можно таким примером:

C++
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
enum a
{
  A=5,
};
 
main()
{
  printf("%d\n", (int)sizeof(enum a));
}
При исполнении напечатается 4 (что соотвествут 32 битам или типу int)
Если сделаешь A=0x1122334455667788LL, то размер будет 8
Humanitis
172 / 164 / 6
Регистрация: 12.01.2009
Сообщений: 430
21.04.2009, 23:31 #8
Цитата Сообщение от Evg Посмотреть сообщение
Насколько я знаю, не запрещает. Хотя мои знания касаются в основном Си.
Цитата из стандарта
The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by
integral promotion (4.5). [ Example:
enum color { red, yellow, green=20, blue };
color col = red;
color* cp = &col;
if (*cp == blue) // ...
makes color a type describing various colors, and then declares col as an object of that type, and cp as a
pointer to an object of that type. The possible values of an object of type color are red, yellow, green,
blue these values can be converted to the integral values 0, 1, 20, and 21. Since enumerations are distinct
types, objects of type color can be assigned only values of type color.
color c = 1; // error: type mismatch,
// no conversion from int to color
int i = yellow; // OK: yellow converted to integral value 1
// integral promotion
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
21.04.2009, 23:35  [ТС] #9
Ой,блин,вот же я даю
Я ОШИБСЯ =)
Всё то же самое,но я хотел сказать
C++
1
2
enum e1{a=3,b=9};
e1 c=e1(85);
А вопросы и всё остальное без изменения(теперь понятно почему у некоторых не компилилось).Но вопрос актуален-это проходит компиляцию,и на печать "с" тоже выходит корректно,хотя за пределами диапазона по книге.
Evg
Эксперт CАвтор FAQ
17619 / 5843 / 375
Регистрация: 30.03.2009
Сообщений: 16,118
Записей в блоге: 26
21.04.2009, 23:46 #10
Humanitis

> Цитата из стандарта
Однако ты прав. Правда это дело касается неявного преобразования типа (и только в си++, в си такого запрета нет)

т.е.
C++
1
2
color c = 1; // по стандарту действительно запрещено неявное преобразовние
color c = (enum color)1; // а это действо разрешено
Собственно, это ещё одно место, где идёт различие в поведении Си и Си++

Добавлено через 1 минуту 42 секунды
Цитата Сообщение от #pragma Посмотреть сообщение
А вопросы и всё остальное без изменения(теперь понятно почему у некоторых не компилилось).Но вопрос актуален-это проходит компиляцию,и на печать "с" тоже выходит корректно,хотя за пределами диапазона по книге.
Я так понял, что ты что-то не понял. Поясни поподробнее, а то прочёл 3 раза и не въехал
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
22.04.2009, 21:58  [ТС] #11
Цитата Сообщение от Evg Посмотреть сообщение
Я так понял, что ты что-то не понял. Поясни поподробнее, а то прочёл 3 раза и не въехал
В-общем,почему при присваивании "e1 c =e1(85)" в "с" содержится корректное значение,о чём свидетельствует вывод на печать?Ведь оно не определено по стандарту,так как за пределами диапазона перечисления.
Evg
Эксперт CАвтор FAQ
17619 / 5843 / 375
Регистрация: 30.03.2009
Сообщений: 16,118
Записей в блоге: 26
22.04.2009, 22:00 #12
В выражение "e1 c =e1(85)" у фактически означает "e1 c = (e1) 85", т.е. содержит ЯВНОЕ преобразование int'а в enum. А по стандарту запрещено только НЕЯВНОЕ
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
22.04.2009, 22:06  [ТС] #13
А можешь пример привести,что такое неявное преобразование?
Evg
Эксперт CАвтор FAQ
17619 / 5843 / 375
Регистрация: 30.03.2009
Сообщений: 16,118
Записей в блоге: 26
22.04.2009, 22:50 #14
Поясню на int'е и float'е, т.к. мне кажется, что это более понятно

C++
1
2
3
4
int i;
float = f;
i = f; // неявное преобразование, т.к. справа и слева от присваивания переменные разных типов
i = (int) f; // действие то же самое, но при этом программист операцию преобразования написал явно
Добавлено через 31 минуту 34 секунды
Да, вот ещё неявное преобразование

C++
1
2
3
4
5
int i;
float f;
double d;
i = f + d; // здесь операция сложения над разными типами, по стандарту в этом случае второй аргумент приводится к формату первого (неявное преобразование), то же касается операции присваивания
i = (int)(f + (float)d); // а это то же самое, но у же с явными преобразованиями
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.04.2009, 22:50
Привет! Вот еще темы с ответами:

Перечисления (enum): для чего они нужны? Как, когда и какими перечислениями уместнее пользоваться? - C++
Предположим есть такой код: #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;Windows.h&gt; enum airplanes {SU6, SU29, SU34}; //...

Запросить с консоли целое число и проверить его на попадание в заданный диапазон значений - C++
Задания 1. Запросить с консоли целое число и проверить его на попадание в заданный диапазон значений. Результат такой проверки вывести на...

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

Enum == int !=enum? - C++
enum Flags{ Flag1 = 1, Flag2 = 2}; int main() { Flags a = Flag1, b = Flag2; a = a | b; } error C2440: =: невозможно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
22.04.2009, 22:50
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru