Three things are being declared here: an anonymous enumerated type is declared, `ShapeType` is being declared a typedef for that anonymous enumeration, and the three names `kCircle`, `kRectangle`, and `kOblateSpheroid` are being declared as integral constants.
Let's break that down. In the simplest case, an enumeration can be declared as
enum tagname { ... };
This declares an enumeration with the tag `tagname`. In C and Objective-C (but *not* C++), any references to this *must* be preceded with the `enum` keyword. For example:
enum tagname x; // declare x of type 'enum tagname'
tagname x; // ERROR in C/Objective-C, OK in C++
In order to avoid having to use the `enum` keyword everywhere, a typedef can be created:
enum tagname { ... };
typedef enum tagname tagname; // declare 'tagname' as a typedef for 'enum tagname'
This can be simplified into one line:
typedef enum tagname { ... } tagname; // declare both 'enum tagname' and 'tagname'
And finally, if we don't need to be able to use `enum tagname` with the `enum` keyword, we can make the `enum` anonymous and only declare it with the typedef name:
typedef enum { ... } tagname;
Now, in this case, we're declaring `ShapeType` to be a typedef'ed name of an anonymous enumeration. `ShapeType` is really just an integral type, and should only be used to declare variables which hold one of the values listed in the declaration (that is, one of `kCircle`, `kRectangle`, and `kOblateSpheroid`). You can assign a `ShapeType` variable another value by casting, though, so you have to be careful when reading enum values.
Finally, `kCircle`, `kRectangle`, and `kOblateSpheroid` are declared as integral constants in the global namespace. Since no specific values were specified, they get assigned to consecutive integers starting with 0, so `kCircle` is 0, `kRectangle` is 1, and `kOblateSpheroid` is 2.