Подтвердить что ты не робот

#define или enum?

Возможный дубликат:
Зачем использовать перечисление, когда #define так же эффективно?

При программировании на языке C лучше использовать #define-инструкции или перечисления для состояний в конечной машине?

4b9b3361

Ответ 1

Поскольку состояния являются связанными элементами, я думаю, что лучше иметь перечисление, определяющее их.

Ответ 2

Технически это не имеет значения. Компилятор, скорее всего, даже создаст идентичный машинный код для любого случая, но перечисление имеет три преимущества:

  • Используя правую комбинацию компилятора + отладчика, отладчик будет печатать переменные перечисления по имени перечисления, а не по их числу. Итак, "StateBlahBlup" читает гораздо приятнее, чем "41", не так ли?

  • Вы явно не указываете каждому государству число, компилятор делает нумерацию для вас, если вы ее разрешите. Предположим, что у вас уже есть 20 состояний, и вы хотите добавить новое состояние посередине, в случае определений вам нужно все перенумеровать самостоятельно. В случае перечисления вы можете просто добавить состояние, и компилятор изменит нумерацию всех состояний ниже этого нового состояния.

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

Ответ 3

Нет окончательного ответа. enum предлагает вам определение масштаба и автоматического присвоения значений, но не дает никакого контроля над постоянным типом (всегда signed int). #define игнорирует область видимости, но позволяет использовать более удобные средства ввода текста: позволяет выбрать тип константы (либо с помощью суффиксов, либо путем включения явного приведения в определение).

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

Ответ 4

Я предпочитаю перечисление. Они более компактны и более безопасны. Вы также можете указать порядок в перечислении, который может быть полезен в конечной машине. #defines следует избегать, если это возможно, поскольку они будут перезаписывать все вхождения в источнике, что может привести к некоторым непреднамеренным действиям, которые трудно отлаживать.

Ответ 5

Директивы

#define могут иметь множество непредвиденных последствий и не следовать общим правилам определения области. Используйте перечисления при наличии связанных данных.

Дополнительная информация: http://www.embedded.com/columns/programmingpointers/9900402?_requestid=341945 [материал С++, но все же незначительно релевантный]

Ответ 6

Если enum поддерживается вашим компилятором, это было бы предпочтительнее. В противном случае используйте #define. Все компиляторы С++ и современные компиляторы C должны поддерживать enum, но более старые компиляторы (в частности, предназначенные для встроенных платформ) могут не поддерживать enum.

Если вы должны использовать #define, обязательно определите свои константы в круглых скобках, чтобы избежать ошибок препроцессора:

#define RED_STATE    (1)
#define YELLOW_STATE (2)
#define GREEN_STATE  (3)

Ответ 7

Вы можете сделать этот трюк, чтобы заставить компилятор проверить тип значения #define.

#define VALUE_NAME ((TYPE_NAME) 12)

Однако реальная проблема #define заключается в ее переопределении в коде приложения. (Конечно, компилятор предупредит вас об этом.)

Ответ 8

enum отлично работает, когда у вас есть эксклюзивные опции, но вы не можете использовать их для определения битовых полей, например:

#define SQ_DEFAULT 0x0
#define SQ_WITH_RED 0x1
#define SQ_WITH_BLUE 0x2

void paint_square(int flags);

Затем вы можете нарисовать красно-синий квадрат с помощью

paint_square(SQ_WITH_RED | SQ_WITH_BLUE);

... который вы не можете с помощью enum.

Ответ 9

Вы можете использовать все, что хотите и как.

Как все говорят, я также хотел бы добавить меня в качестве голосования за Enums.

Перечисления всегда должны быть предпочтительными, если вы используете связанные данные, как в случае машины состояния, вы также можете определить порядок в перечислениях, который поможет в реализации State Machine.

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

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

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