Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Количество элементов в множестве (enum)

1.9K
19 ноября 2003 года
XilefNori
34 / / 28.02.2003
Предположим у меня есть перечисление вида

enum TERRAINS
{
UNKNOWN_TERRAIN = -1,
FOREST,
BASIN,
DESERT,
ROAD,
HOBITATION,
LEA,
DANGERZONE
};

Вопрос: Можно ли узнать сколько элеметов в данном перечислении, чем-нибудь вроде sizeof()?
293
19 ноября 2003 года
SEDEGOFF
586 / / 06.10.2002
Скажи пожалалуйста - а тебе зачем, ведь ты сам создаешь все
1.9K
19 ноября 2003 года
XilefNori
34 / / 28.02.2003
Цитата:
Originally posted by SEDEGOFF
Скажи пожалалуйста - а тебе зачем, ведь ты сам создаешь все



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


//----------------------------------------------------------
// Имена файлов
//----------------------------------------------------------
const AnsiString GraphFiles[] =
{
"pics\\F5n5.bmp",
"pics\\F5n5nums.bmp",
"pics\\z.bmp",
"pics\\z3.bmp"
};

//----------------------------------------------------------
// Номера файлов
//----------------------------------------------------------
enum GraphFileNumbers
{
LEEFILE = 0,
LEEFILE2,
ZFACE,
ZFACER
};

const int GraphFilesNum = 4;

//----------------------------------------------------------
// Сообщения об ошибках
//----------------------------------------------------------
AnsiString ErrorMess[] =
{
"Нет файла поля!",
"Нет файла поля!",
"Нет файла zf!",
"Нет файла zfr!"
};
//----------------------------------------------------------
// Функуция проверки наличия всех необходимых файлов
//----------------------------------------------------------

void CheckRes()
{
for (int i=LEEFILE;i<GraphFilesNum;i++)
{
if (!FileExists(GraphFiles)) throw Exception(ErrorMess);
}
}


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

1.9K
19 ноября 2003 года
ILS
100 / / 28.01.2003
Цитата:
Originally posted by XilefNori

enum GraphFileNumbers
{
LEEFILE = 0,
LEEFILE2,
ZFACE,
ZFACER
};

const int GraphFilesNum = 4;



Если ты используешь перечисления без присвоений внутри (меняющих их порядок по умолчанию: от 0 и далее +1), то последний элемент и есть количество.
Например:
enum GraphFileNumbers
{
LEEFILE ,//= 0 - оно и так =0 - по умолчанию
LEEFILE2,
ZFACE,
ZFACER,
GraphFilesNum
};
Т.е. теперь ты всегда уверен, что GraphFilesNum и есть кол-во

3
19 ноября 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by XilefNori
Предположим у меня есть перечисление вида

enum TERRAINS
{
UNKNOWN_TERRAIN = -1,
FOREST,
BASIN,
DESERT,
ROAD,
HOBITATION,
LEA,
DANGERZONE
};

Вопрос: Можно ли узнать сколько элеметов в данном перечислении, чем-нибудь вроде sizeof()?



Нет, нельзя. Перечисление, вообще, не имеет "физического" представления, т.е. не занимает места, не имеет размера и т.д.

Что касаемо GraphFilesNum, то оно связано на мой взгляд с GraphFiles[], а не enum:

const int GraphFilesNum = sizeof(GraphFiles)/sizeof(GraphFiles[0]);

1.9K
19 ноября 2003 года
XilefNori
34 / / 28.02.2003
Цитата:
Originally posted by ILS

enum GraphFileNumbers
{
LEEFILE ,//= 0 - оно и так =0 - по умолчанию
LEEFILE2,
ZFACE,
ZFACER,
GraphFilesNum
};



Разумно.
Других вариантов нет?

1.9K
19 ноября 2003 года
XilefNori
34 / / 28.02.2003
Цитата:
Originally posted by Green

Нет, нельзя. Перечисление, вообще, не имеет "физического" представления, т.е. не занимает места, не имеет размера и т.д.



Ага.

Цитата:
Originally posted by Green

Что касаемо GraphFilesNum, то оно связано на мой взгляд с GraphFiles[], а не enum:



Резонно.

Цитата:
Originally posted by Green

const int GraphFilesNum = sizeof(GraphFiles)/sizeof(GraphFiles[0]);



Проверил. Работает. Хотя с моей точки зрения не должно: длины названий файлов разные.

1.9K
19 ноября 2003 года
ILS
100 / / 28.01.2003
Цитата:
Originally posted by XilefNori


Разумно.
Других вариантов нет?


Этот не устраивает ? Или сомневаешься - вот кусок моего кода:
enum { cl_Screen=0, // фон экрана
....
....
cl_ErrorMsg, // сообщения об ошибках
cl_HotKeys, // @горячие@ клавиши
cl_ //
};
....
....
unsigned char Clrs[cl_];

Enumы хотя и могут именоваться, но не подвержены sizeof-у - их действительно нет во время исполнения - о них "знал" лишь компилятор...

3
19 ноября 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by XilefNori

Проверил. Работает. Хотя с моей точки зрения не должно: длины названий файлов разные.



Длины названий здесь не имеют значения.

GraphFiles[] - массив const AnsiString
sizeof(GraphFiles) - размер этого массива
sizeof(GraphFiles[0]) - размер элемента массива, т.е. sizeof(AnsiString).

1.9K
19 ноября 2003 года
XilefNori
34 / / 28.02.2003
Цитата:
Originally posted by ILS

Этот не устраивает? Или сомневаешься...


Да нет. Просто интересно есть ли другие решения.

Цитата:
Originally posted by ILS

Enumы хотя и могут именоваться, но не подвержены sizeof-у - их действительно нет во время исполнения - о них "знал" лишь компилятор...


Got it!

Цитата:
Originally posted by Green

GraphFiles[] - массив const AnsiString
sizeof(GraphFiles) - размер этого массива
sizeof(GraphFiles[0]) - размер элемента массива, т.е. sizeof(AnsiString).


Это ясно. Однако не ясно почему AnsiString имеет такой странный размер: всего 4 байта?

Да еще вопрос:
Можно ли пробежаться по всем значениям перечисления enum в цикле, если они не составляют арифметическую последоватьность, вроде:

enum E
{
E1 = 0,
E2,
E3 = -3,
E4 = 102,
E5 = 8
};
?

3
19 ноября 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by XilefNori

Это ясно. Однако не ясно почему AnsiString имеет такой странный размер: всего 4 байта?



Размер класса определяется суммарным размером входящих в него членов данных с учетом выравнивания.
Т.о. получается, что AnsiString, видимо, имеет один такой член - указатель на строку.

Цитата:
Originally posted by XilefNori

Да еще вопрос:
Можно ли пробежаться по всем значениям перечисления enum в цикле, если они не составляют арифметическую последоватьность, вроде:

enum E
{
E1 = 0,
E2,
E3 = -3,
E4 = 102,
E5 = 8
};
?



Нет. Хотя, вопрос не совсем понятен.

1.9K
19 ноября 2003 года
XilefNori
34 / / 28.02.2003
Цитата:
Originally posted by Green

Размер класса определяется суммарным размером входящих в него членов данных с учетом выравнивания.
Т.о. получается, что AnsiString, видимо, имеет один такой член - указатель на строку.


Т.е. допустим:
если данные занимают int x - байт, а память квантуется по int i байт, то в случае если x%i!=0, то под эти данные выделится память размером (x/i)*(i+1)?

Я такого не замечал. Можно ссылочку кинуть на тему этого таинственного выравнивания?

Цитата:
Originally posted by Green

Нет. Хотя, вопрос не совсем понятен.


Ну например написать что-нибудь вроде:

for(int i=E.begin(); i!=E.end(); i++)
{
Check(i);
}

3
19 ноября 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by XilefNori

Т.е. допустим:
если данные занимают int x - байт, а память квантуется по int i байт, то в случае если x%i!=0, то под эти данные выделится память размером (x/i)*(i+1)?

Я такого не замечал. Можно ссылочку кинуть на тему этого таинственного выравнивания?



Посмотри опции компилятора. Для VC++ это /Zp.
А также #pragma pack

Цитата:
Originally posted by XilefNori

Ну например написать что-нибудь вроде:

for(int i=E.begin(); i!=E.end(); i++)
{
Check(i);
}



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

415
19 ноября 2003 года
SLA
274 / / 08.08.2003
Цитата:
Originally posted by ILS
Enumы хотя и могут именоваться, но не подвержены sizeof-у - их действительно нет во время исполнения - о них "знал" лишь компилятор...



Кстати, sizeof() в данном случае тоже вычисляется еще при компиляции программы.

1.9K
20 ноября 2003 года
ILS
100 / / 28.01.2003
Цитата:
Originally posted by SLA


Кстати, sizeof() в данном случае тоже вычисляется еще при компиляции программы.


он м.б. и вычисляется - но как ?
проверь сам на практике (в отладчике):
enum E
{
E1,
E2,
E3,
E4,
E5
};
...
int e=sizeof(E);
...
- посмотри чему равно е...

3
20 ноября 2003 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by SLA

Кстати, sizeof() в данном случае тоже вычисляется еще при компиляции программы.



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

int e = sizeof E;

Цитата:
Originally posted by ILS

он м.б. и вычисляется - но как ?
проверь сам на практике (в отладчике):
enum E
{
E1,
E2,
E3,
E4,
E5
};
...
int e=sizeof(E);
...
- посмотри чему равно е...



sizeof для enum это размерность наименьшего (по размерности) типа, который может содержать наибольшее значение из enum. Но этот тип по размерности не больше int.
Может, коряво сказал, но в кратце sizeof для enum будет 1, 2 или 4, в зависимости от разрядности максимального значения.
Правда, это было действительно для 32-битных архитектур. Возможно, что для 64-битных sizeof может быть и 8.

415
20 ноября 2003 года
SLA
274 / / 08.08.2003
Цитата:
Originally posted by Green
sizeof всегда вычисляется при компиляции


Действительно, так и есть. Я вчера в кое-какие доки заглянул чтобы уточнить.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог