Что означает следующее в отношении перечислений в программировании на C?

#c #types #enums

#c #типы #перечисления

Вопрос:

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

 enum corvid { magpie, raven, jay, corvid_num};  char const * const bird [ corvid_num ] =  {  [raven] = "raven",  [magpie] = "magpie",  [jay] = "jay", };  for ( unsigned i = 0; i lt; corvid_num ;   i)  printf ("Corvid %u is the %sn", i, bird[i]);  

Это объявляет новый целочисленный тип enum corvid, для которого мы знаем четыре разных значения.

Константы перечисления на вынос имеют либо явное, либо позиционное значение

Как вы могли догадаться, позиционные значения начинаются с 0 и далее, поэтому в нашем примере у нас есть ворон со значением 0, сорока с 1, сойка с 2 и corvid_num с 3. Эти последние 3, очевидно, являются теми 3, которые нас интересуют.

Вопрос 1:

[magpie] = "magpie" Подразумевает, что magpie эта позиция относится к ценности "magpie" .

Вопрос 2:

Согласно циклу, как bird[0] равно "raven" , так как это явное, а не позиционное значение. Также после первой итерации будет [i 1] равно [magpie] . В целом, почему тип переменной цикла без знака, а не corvid или перечисление corvid?

Я думаю, что неправильно понял константы перечисления.

Также из,

Как вы могли догадаться, позиционные значения начинаются с 0 и далее, поэтому в нашем примере мы имеем raven значение 0, magpie 1, jay 2 и corvid_num 3. Эти последние 3, очевидно, являются теми 3, которые нас интересуют.

Прав ли автор, говоря, что ворон должен иметь значение 0, а не сорока, если это опечатка, вся моя путаница исчезнет.

Комментарии:

1. Автор ошибается. Поскольку значения явно не назначены, первое перечисление будет равно нулю, а следующее будет увеличено на 1. Итак, для перечислений сорока равна 0 , ворон равен 1, джей равен 2, corvid_num равен 3

2. Это опечатка. Вы можете проверить, распечатав значения перечисления, например printf("%dn", magpie); , будет выведено 0.

3. Это необычный способ инициализации массива..

4. @hetepeperfan почему странный? Это простой способ сопоставить значения перечисления с его именем, чтобы при необходимости распечатать их. Это также безопасно в случае, если вы добавляете новые значения в середине списка перечислений.

5. @alagner это стандартный C начиная с C99. Возможно, вы имеете в виду расширение для C

Ответ №1:

В объявлении char const * const bird [ corvid_num ] элемент между [ ] -это размер массива. В списке инициализаторов [ raven ] = " raven " элемент между [ ] является так называемым назначенным инициализатором, используемым для инициализации определенного элемента в массиве.

Вопрос 1 : Означает ли «[сорока] = «сорока», что позиция «сорока» относится к значению «сорока».

ДА.

Вопрос 2 : Согласно циклу, как птица [0] равна «ворону» , поскольку это явное, а не позиционное значение.

Потому что перечисления называются константами. Если константе перечисления ( raven и т.д.) Не задано число явно, оно задается неявно, начиная с 0. raven В вашем примере это второй элемент в перечислении, поэтому он получает значение 1, и всякий раз, когда вы вводите raven исходный код, это будет эквивалентно вводу 1 .

Как вы могли догадаться, позиционные значения начинаются с 0 и далее, поэтому в нашем примере у нас есть ворон со значением 0, сорока с 1, сойка с 2 и corvid_num с 3. Эти последние 3, очевидно, являются теми 3, которые нас интересуют.

Это ошибка в Густедте — Современном С. Могут существовать ошибки? Вывод из примера кода выглядит следующим образом:

 Corvid 0 is the magpie Corvid 1 is the raven Corvid 2 is the jay  

Примечательно, что если бы мы не использовали назначенные инициализаторы, а просто сделали это:

 char const * const bird [ corvid_num ] =  {  "raven",  "magpie",  "jay", };  

Тогда выход вместо этого стал бы

 Corvid 0 is the raven Corvid 1 is the magpie Corvid 2 is the jay  

Ответ №2:

Каждый enum случай получает значение предыдущего случая плюс один, если только он явно не переопределен, а в первом случае значение равно нулю. Так вот magpie 0 , raven есть 1 , есть и т. Д. (Цитируемая часть, говорящая об обратном, неверна.) Последний случай corvid_num -это количество других случаев в массиве, так 1 как в начале этот случай равен нулю.

Инициализация массива выполняется с использованием инициализаторов, назначенных C99, которые позволяют присваивать значения определенным индексам и в любом порядке, т. е. [raven] = "raven" инициализировать индекс raven (здесь 1 ). Можно было бы просто традиционно перечислять каждое значение по порядку, но это позволяет переупорядочивать случаи перечисления без необходимости синхронизации изменений с массивом.