Разница между использованием переменных enum и int в C - PullRequest
4 голосов
/ 04 августа 2020

В чем разница между

enum week{Mon, Tue, Wed, Thur, Fri, Sat, Sun};
enum week day = Wed; 

и

enum week{Mon, Tue, Wed, Thur, Fri, Sat, Sun};
int day = Wed;

в C?

Я не смог найти, в чем преимущество использования переменных типа enum вместо обычного int.

Ответы [ 3 ]

8 голосов
/ 04 августа 2020

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

switch (day) {
    case Mon: printf("Monday\n"); break;
    case Tue: printf("Tuesday\n"); break;
}

Здесь G CC (с -Wall) выдает:

предупреждение: значение перечисления 'Wed' не обрабатывается в переключателе [-Wswitch]

7 |     switch (day) {
  |     ^~~~~~

Если тип day был int , вы бы не получили это очень полезное предупреждение.

2 голосов
/ 04 августа 2020

Идентификаторы / константы enum имеют тип int, поэтому их значения допустимо присваивать переменным int:

"Идентификаторы в списке перечислителя объявлены как константы, которые имеют тип int и могут появляться везде, где это разрешено. "

C18, §6.7.7.2 / 3

Однако тип перечисления может варьируются в зависимости от реализации:

"Каждый перечислимый тип должен быть совместим с char, целочисленным типом со знаком или целочисленным типом без знака. Выбор типа определяется реализацией, 131), но должен быть может представлять значения всех членов перечисления ".

C18, §6.7.7.2 / 4

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

Другое дело, что легко можно присвоить константу другого типа enum day, если он имеет тип int.

enum week {Mon, Tue, Wed, Thur, Fri, Sat, Sun};
enum month {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dez};

int day = Mar;

Это компилируется без проблем.

Высокоуровневый компилятор может выдавать предупреждение об этом при использовании типа enum week вместо day и добавляет этим дополнительный уровень безопасности.

enum week {Mon, Tue, Wed, Thur, Fri, Sat, Sun};
enum month {Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};

enum week day = Mar;

Например, Clang, 10.0 выдает без дополнительных флагов:

" предупреждение: неявное преобразование из типа перечисления 'enum month' в другой тип перечисления 'enum week' [-Wenum- преобразование]"

G CC, 10.1 требуется флаг -Wall или -Wenum-conversion, чтобы выдать такое же предупреждение.

Также в этом посте рассматривается аналогичная проблема, но я бы не стал go объявлять его дубликатом:

Кроме того, я нашел эту интересную статью:

1 голос
/ 04 августа 2020

Перечисления в C - удобный способ создания символьных c констант для небольших наборов вещей, которые не обязательно упорядочены.

Они не высокоуровневые абстракция в C так же, как в Java или C#. Они целочисленные типы под капотом, и поскольку C верит, что вы всегда знаете, что делаете, и никогда, никогда не допускаете ошибок, он не жалуется, когда вы смешиваете и сопоставляете * Типы 1007 * и int.

...