2016-03-18 1 views
2

В C, даже следующий код выдает ошибку (из-за orange):Могут ли перечисления быть заменены на consts в C?

enum color {yellow, blue, green, red, brown, black, white, purple, orange}; 
enum fruit {cherry, apple, pear, melon, banana, strawberry, raspberry, orange}; 

Но такой код:

enum fruit {cherry = 1, apple = 2, pear = 3, melon = 4, banana = 5, strawberry = 6, raspberry = 7, orange = 8}; 

int main(int argc, char *argv[]){ 
    enum fruit f; 
    int x; 

    x = apple; 
    f = -7; 

    return 0; 
} 

компилирует с gcc --std=c89 -pedantic.

кажется enum s может быть легко заменен const переменными:

typedef int fruit; 
const fruit cherry = 1, apple = 2, pear = 3, melon = 4, banana = 5, strawberry = 6, raspberry = 7, orange = 8; 

int main(int argc, char *argv[]){ 
    fruit f; 
    int x; 

    x = apple; 
    f = -7; 

    return 0; 
} 

только образом enum ведет себя по-разному isthat вы абсолютно не может изменить значение cherry, apple, ..., в то время как с помощью const сек можно попробовать обычные трюки, такие как int *y = &apple; *y = -7;gcc Я получаю предупреждение, но оно компилируется).

Разве это единственное различие или я что-то пропустил?

+1

'сопзЬ фруктовым яблоко = 1; int * y = &apple; * y = -7; '. Неопределенное поведение - это то, что вы получаете для изменения переменной 'const'. ** Редактировать **: По-видимому, это скорее называется «нарушение ограничения», и для реализации этого требуется реализация C. – 3442

+0

Какой смысл объявлять его 'const', если вы собираетесь его изменить? – axiac

+0

Лучший вопрос: зачем нужен 'const', когда вы можете просто использовать константы enum ?, которые гарантированно создадут эффективный машинный код как буквенные числа, а значения' const' зависят от оптимизации. – hyde

ответ

4

Существует несколько существенных отличий между константами enum и const -qualified объектов.

Декларация enum типа, такие как

enum fruit {cherry, apple, pear}; 

автоматически связывает последовательные значения начиная с 0 к константам cherry, apple и pear. (Вы можете переопределить эти значения, если хотите.) Это означает, что (a) вы можете переставить константы по своему усмотрению, а компилятор позаботится о значениях, и (б) меньше вероятность случайного использования неправильных значений.

Альтернативой таких как:

const int cherry = 0; 
const int apple = 1; 
const int pear = 2; 

труднее поддерживать - и, пожалуй, самое главное, имена cherry и др не являются постоянными выражениями. Это означает, например, что вы не можете использовать их в методах case или в любом другом контексте, требующем постоянного выражения.

Что касается изменения значения объекта const -qualified, то это прямое нарушение , требующее диагностики времени компиляции. (gcc имеет тенденцию делать такую ​​диагностику нефатальными предупреждениями по умолчанию.) Вы можете попытаться изменить ее косвенно, например, используя приведение указателя, но это имеет неопределенное поведение.

Одна вещь, чтобы помнить о enum типов C является то, что константы имеют тип int, не из перечислимого типа. Обычно это не имеет значения, поскольку в большинстве контекстов значение будет неявно преобразовано в правильный тип. (C++ имеет различные правила, но вопрос о С)

0

enum обычно используется в качестве логических переменных, которые вы упомянули в вашем примере, например, color и fruit, где вы действительно не заботятся о фактическом численном значении каждый элемент, а скорее то, что он представляет.

const с другой стороны, обычно используется, когда вы действительно заботитесь о численном значении. Например:

const float PI = 3.1415926; 

Так как для вашего вопроса, ответ да, то перечисление можно заменить константными значениями, но вопрос в том, есть ли истинный вариант использования для него

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