In a book I'm reading, enumeration constants have been introduced before arrays. Use of arrays has been demonstrated only through a couple examples. Following is stated :
enum corvid { magpie, raven, jay, corvid_num};
char const * const bird [ corvid_num ] =
{
[raven] = "raven",
[magpie] = "magpie",
[jay] = "jay",
};
for ( unsigned i = 0; i < corvid_num ; i)
printf ("Corvid %u is the %s\n", i, bird[i]);
This declares a new integer type enum corvid for which we know four different values.
Takeaway - Enumeration constants have either an explicit or a positional value
As you might have guessed, positional values start from 0 onward, so in our example we have raven with value 0, magpie with 1, jay with 2, and corvid_num with 3. This last 3 is obviously the 3 we are interested in.
Question 1:
Does [magpie] = "magpie"
imply that magpie
th position refers to value "magpie"
.
Question 2:
According to loop, how is bird[0]
equal to "raven"
, since this is explicit and not a positional value. Also after the first iteration is [i 1]
gonna be equal to [magpie]
. In all why is loop variable's type unsigned and not corvid or enum corvid?
I think I have misunderstood enumeration constants.
Also from,
As you might have guessed, positional values start from 0 onward, so in our example we have
raven
with value 0,magpie
with 1,jay
with 2, andcorvid_num
with 3. This last 3 is obviously the 3 we are interested in.
Is author right to say that raven should have value 0 and not magpie, if this is a typo, entirety of my confusion will dispense.
CodePudding user response:
In the declaration char const * const bird [ corvid_num ]
the item between [ ]
is the size of the array. In the initializer list, [ raven ] = " raven "
, the item between [ ]
is a so-called designated initializer, used to initialize a particular item in the array.
Question 1 : Does ' [ magpie ] = " magpie "' imply that 'magpie'TH position refers to value "magpie".
Yes.
Question 2 : According to loop, how is bird [0] equal to "raven" , since this is explicit and not a positional value.
Because enums are named constants. If an enumeration constant (raven
etc) isn't given a number explicitly, it is given one implicitly, starting at 0. raven
in your example is the second item in the enum, so it gets value 1 and whenever you type raven
in the source it will be equivalent to typing 1
.
As you might have guessed, positional values start from 0 onward, so in our example we have raven with value 0, magpie with 1, jay with 2, and corvid_num with 3. This last 3 is obviously the 3 we are interested in.
This is an error in Gustedt - Modern C. Errata might exist? The output from the example code is:
Corvid 0 is the magpie
Corvid 1 is the raven
Corvid 2 is the jay
Notably, if we had not used designated initializers but just done this:
char const * const bird [ corvid_num ] =
{
"raven",
"magpie",
"jay",
};
Then the output would instead have become
Corvid 0 is the raven
Corvid 1 is the magpie
Corvid 2 is the jay
CodePudding user response:
Each enum
case gets the value of the previous case plus one, unless explicitly overridden, and the first case gets the value zero. So here magpie
is 0
, raven
is 1
, etc. (The quoted part saying otherwise is wrong.) The final case corvid_num
is the count of other cases in the array, since the 1
of that case accounts for the zero case in the beginning.
The array initialisation is using C99 designated initializers, which allows assigning values to specific indices and in any order, i.e., [raven] = "raven"
initialises the index raven
(here 1
). It would be possible to just traditionally list each value in order, but doing it this way allows reordering the enum cases without having to sync the changes with the array.