Зачем нам нужно объявлять переменные перечисления? (C) - PullRequest
0 голосов
/ 29 февраля 2020

Я начинаю изучать C язык впервые. Этот вопрос может показаться довольно простым c, но я буду признателен за любую помощь!

мой вопрос, если бы вы просто могли сделать

enum day {
    mon, tue, wed
};

int main() {
    int today = mon; 
    return 0;
}

, чтобы установить переменную "сегодня" в 0, почему большинство учебников пишут как

enum day {
    mon, tue, wed
}today;

int main() {
    today = mon; 
    return 0;
} 

Я вижу enum как нечто вроде класса. Поэтому нет смысла указывать переменную, которая использует перечисление. Почему второй способ написания более распространен?

Ответы [ 3 ]

2 голосов
/ 01 марта 2020

Перечисления были добавлены к языку C с опозданием. Как следствие, они не являются «строго типизированными» - C мало чем отличается от guish их от других целочисленных значений, и поэтому они во многом удобны.

В теории, Вы можете объявить объект типом перечисления, чтобы указать, что он должен содержать некоторое значение из перечисления, а не любое другое. Стандарт C не требует его применения. Некоторые компиляторы могут предупреждать о нарушениях этого при некоторых обстоятельствах, но они не могут отловить их все.

Каждый идентификатор в перечислении имеет значение int. Из-за этого люди используют их как способ определения констант времени компиляции. Часто это простые последовательные константы, например, для числа дней недели, но они также могут быть произвольными константами, такими как битовые маски или адреса памяти (в пределах диапазона int). Это не является их истинным назначением, но это то, для чего они полезны, поэтому люди используют его.

Тип перечисления и любые объекты, определенные для него, такие как то, что вы объявляете enum day today, должны иметь тип совместим с некоторым целочисленным типом. Например, если все значения в перечислении находятся в диапазоне char, тип перечисления может фактически составлять char. Это означает, что в структуре может потребоваться меньше места, чем при объявлении int. Однако стандарт C не требует, чтобы компилятор использовал наименьший целочисленный тип, который подходит, поэтому эта функция бесполезна для того, чтобы полагаться на перечисления для ограничения используемого пространства.

Стандарт C также не делает требовать каких-либо предупреждений, когда некоторому общему целочисленному значению присваивается объект перечисления. При существующем дизайне перечислений это на самом деле невозможно - поскольку идентификаторы перечисления являются int значениями, правая часть любого присваивания, которое их использует, как в today = Monday + 1, является, по крайней мере, int, не совсем ясно, значение в перечислении, и компилятору становится трудно диагностировать проблемы.

Из-за этих слабых правил перечисления не существует строгого правила определения объектов как типов перечисления, а не, скажем, , int или char. Можно было бы sh определить что-то, чтобы быть типом перечисления, чтобы передать будущим читателям исходного кода, что это используется для записи вещей в этом типе перечисления, но можно также определить sh, чтобы определить это как uint8_t, чтобы гарантировать использование только одного байта в массиве или структуре. Таким образом, существуют противоречивые причины для выбора, и автору придется выбирать один или другой.

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

0 голосов
/ 29 февраля 2020
enum day {
    mon, tue, wed
};
I am seeing enum as something like a class.

Это неверное утверждение.

enum означает целочисленные константы, которые известны во время компиляции. Если вы не инициализируете его явно, первый член перечисления имеет значение ноль, а следующий - su cc (prev_enum_member).

Перечисления важны, так как они позволяют компилятору выбирать sizeof (enum) и потому что, используя символ вместо жестко закодированной константы, удобнее думать о программе. Таким образом, если у вас большое перечисление, компилятор может заменить его целыми числами по 2 байта, если у вас маленькое перечисление, компилятор может выбирать целые числа по 1 байту, и вам все равно, как это происходит.

0 голосов
/ 29 февраля 2020

перечисления в действительности целые числа. Они используются для корректности типа кода, лучшей читабельности, лучшего обмена сообщениями об ошибках (современные компиляторы могут даже предупредить вас, если не все перечисления использовались в switch ... case) и для более удобной отладки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...