2013-07-20 2 views
0

Я использовал много флажков перечисления на языке программирования C. Очень хорошее решение. Но теперь у меня проблема: мне нужно реализовать более 32 флаговых опций, это 1 << 32, что enum не может удерживать, потому что это слишком большое значение.Заменить флаги перечисления в C

Итак, как я могу это исправить? возможно, следует использовать #define вместо enum и unsigned long int вместо unsigned int? Будет ли это работать нормально? a structс битовыми полями не подходит для меня, потому что это нет C ANSI стандартный код.

+3

Что вы говорите, что битполы не являются стандартными? –

+0

Ну, некоторые здесь, на SO ... «не используют битовые поля, не переносимы» –

+1

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

ответ

1

Вы должны просмотреть static const vs #define in C.

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

enum 
{ 
    FLAG_A = 0x00000001, FLAG_B = 0x00000002, FLAG_C = 0x00000004, FLAG_D = 0x00000008, 
    ... 
}; 

Вы также объединить эти различные значения перечисления в (32-бит) unsigned int значение с поразрядными операций. Теперь вы достигли предела; у вас более 32 флагов (и я надеюсь, что они более значимо названы, чем в моем примере).

Вы можете решить начать новую серию перечислений, используя второе 32-разрядное (без знака) целое число для хранения бит. Это имеет смысл хранить символы в отлаживаемой программе (в отличие от констант #define, которые редко доступны даже в отлаживаемых программах). Недостатком является то, что вам может потребоваться передать два значения, где ранее вы их передали.

Если необходимо сохранить флаги в одной переменной, вам нужно будет проверить, лучше ли использовать unsigned long long, или, возможно, структура с двумя значениями unsigned int будет работать.

Я согласен, что лучше не использовать битовые поля, хотя они могут работать достаточно хорошо. Я бы также пошел на значительные усилия, чтобы избежать использования #define и, вероятно, использовал бы либо две 32-битные переменные, либо структуру. Многое зависит от вашей базы кода и от того, насколько широко используются значения.

0

Вы можете позволить своим enum значениям следовать порядковому порядку значений, что позволит до INT_MAX + 1 перечислять значения. Но, если у вас меньше, чем 64, то вы можете использовать unsigned long long нести множество значений:

unsigned long long set_MyEnum (unsigned long long my_enum_set, enum MyEnum e) { 
    return my_enum_set | (1U << e); 
} 

unsigned long long unset_myEnum (unsigned long long my_enum_set, enum MyEnum e) { 
    return my_enum_set & ~(1U << e); 
} 

int is_set_MyEnum (unsigned long long my_enum_set, enum MyEnum e) { 
    return my_enum_set & (1U << e); 
} 

Если у вас есть 64 или больше, то вы можете определить набор быть какой-то массив.

 Смежные вопросы

  • Нет связанных вопросов^_^