Я уже слышал, что должен просто позволить компилятору выбирать, какие значения присваивать перечисляемым константам, если я не делаю чего-то умного, например, использую значения в качестве битовых масок. Если я просто использую значения перечисления для более подробной документации кода, есть ли какие-либо ошибки, которые могут возникнуть, если я не определю явно все значения? Я считаю, что значения присваиваются в порядке возрастания. Должен ли я определить 1-е значение, чтобы обеспечить одинаковые значения для каждой последующей компиляции?
Должен ли я явно определять значения моих перечисляемых констант
Ответы (2)
Я думаю, это будет зависеть от вашего использования типа.
Преимущества отсутствия инициализаторов enum
:
- Легче добавлять и удалять значения по мере разработки.
- Вы не сможете случайно определить два идентификатора с одинаковым значением.
Преимущества предоставления инициализаторов enum
:
- Безопасно сериализовать и десериализовать данные. Если вам нужно поместить эти значения в файл, сетевой сокет и т. д., я бы пошел дальше и написал значения.
- Легче искать значения для целей отладки.
Из C99, раздел 6.7.2.2p3:
Идентификаторы в списке перечислителя объявляются как константы типа int и могут появляться везде, где это разрешено. Перечислитель со знаком = определяет свою константу перечисления как значение константного выражения. Если у первого перечислителя нет =, значение его константы перечисления равно 0. Каждый последующий перечислитель без = определяет свою константу перечисления как значение константного выражения, полученного путем прибавления 1 к значению предыдущей константы перечисления. (Использование перечислителей со знаком = может привести к созданию констант перечисления со значениями, дублирующими другие значения в том же перечислении.)
Единственный раз, когда вам нужно присвоить значение первому перечислителю, это если вы хотите, чтобы его значение отличалось от 0
. Обычно вы этого не делаете, поскольку перечислители часто используются для индексации массива.
Ниже приведен простой пример «прибавления 1 к значению предыдущего».
enum {
A,
B,
C = 0,
D,
E
};
int main ()
{
printf("%d\n", A);
printf("%d\n", B);
printf("%d\n", C);
printf("%d\n", D);
printf("%d\n", E);
return 0;
}
Вывод для вышеуказанной программы:
0
1
0
1
2
Единственный «подводный камень», о котором я могу думать, заключается в том, что если вы хотите, чтобы несколько имен enum
представляли одно и то же значение, вы должны не забыть прикрепить их либо прямо рядом с элементом, который вы называете псевдонимом, либо внизу списка enum
. Я предпочитаю последнее, поэтому я могу подсчитать enum
строк, чтобы предсказать, какими будут значения enum
.
enum {
A,
B,
E,
/* aliases below */
C = A,
D = B
};
В противном случае перечислитель похож на литерал int
.
const int
. Это не объект, не имеет адреса и представляет собой постоянное целочисленное выражение времени компиляции.
- person Jens Gustedt; 09.07.2012
const int
взято из стандартного абзаца, который я процитировал, где говорится о константах, имеющих тип int
, но вы правы, что я неправильно это истолковал. Я отредактировал предложение, с уважением
- person jxh; 09.07.2012