C/С++ Создание перечисления с отрицательными значениями, без необходимости его номера

Например, в C/С++ у меня будет код:

typedef enum fruits{
   apple,
   banana,
   lemon,
   orange
} fruit_t;

Что было бы эквивалентно:

typedef enum fruits{
   apple = 0,
   banana = 1,
   lemon = 2,
   orange = 3
} fruit_t;

Однако, я хотел бы, чтобы значения были отрицательными, поэтому они не конфликтуют ни с чем другим. Я мог бы сделать это следующим образом:

typedef enum fruits{
   apple = -1,
   banana = -2,
   lemon = -3,
   orange = -4
} fruit_t;

Но если я хотел бы добавить еще один фрукт, мне нужно назначить другое значение, и если бы я поставил один промежуточный, я должен перенумеровать большую часть его. Есть ли более простой способ сделать это?

Ответы

Ответ 1

Начните с INT_MIN сверху следующим образом:

#include <limits.h>

enum fruits
{
  orange = INT_MIN,
  lemon, 
  ...
}

Per "5.2.4.2.1 Размеры целочисленных типов" и/или "Приложение E/1" стандарта C11 INT_MIN не менее -32767.

INT_MIN определяется путем включения <limits.h>.

Ответ 2

В C вам нужно только указать верхний, а последующие записи будут предыдущей записью +1, это описано в стандартном проекте C99 6.7.2.2 Спецификаторы перечисления, которые говорят (внимание мое):

[...] Перечислитель с = определяет свою константу перечисления как значение константного выражения. Если первый счетчик не имеет =, значение его константы перечисления равно 0. Каждый последующий перечислитель с no = определяет свою константу перечисления как значение выражения константы, полученного добавлением 1 к значению предыдущая константа перечисления. [...]

и формулировка аналогична в стандартном проекте С++ в разделе 7.2 Объявления перечисления абзаца 2.

Итак, просто сделайте что-то похожее на следующее:

#define MIN -4

typedef enum fruits{
   orange = MIN,
   lemon,  
   banana,
   apple,
} fruit_t;

Ответ 3

Добавьте новости вверху. Вам по-прежнему приходится указывать верхний номер.

enum fruit
{
   orange = -4,
   lemon,
   banana,
   apple,
};

Ответ 4

Прежде всего, нет такой вещи, как "C/С++", это два разных языка. Вы не можете смотреть на C как подмножество С++; некоторый юридический код C не будет компилироваться как программа на С++.

Если вы можете использовать С++ 11, я предлагаю вам использовать enum class, который дает строго типизированные перечисления:

enum class Traffic {red , yellow, green};
Traffic t = Traffic::red;

if ( t == Traffic::red )  // to test the value of an enum 

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

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

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

enum class Traffic : char { red, yellow, green }

Если тип не указан, предполагается значение по умолчанию int.

Обратите внимание, что для этого вам нужен компилятор с поддержкой С++ 11.

Ответ 5

Я думаю, вы можете заказать его в любом случае.

Если вы не даете никакого значения, тогда следующий enum примет +1 своего предыдущего значения. Если даже кулак enum не имеет никакого значения, тогда он начнется с 0.

Но хорошая практика - иметь его в правильном порядке.

Ответ 6

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

typedef enum fruits_e {
    APPLE=1,
    BANANA,
    LEMON,
    ORANGE
} fruit_t;

fruit_t eat_fastfood(void) {
    if (! me->healthy())
        return -APPLE;
}