我不认为我从根本上理解枚举是什么,以及什么时候使用它。

例如:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

这里真正声明的是什么?


当前回答

Enum用于为枚举元素赋值,这在struct中无法完成。因此,每次访问完整变量时,我们可以通过在enum中分配给变量的值来完成。默认情况下,它以0赋值开始,但我们可以为它赋任何值,enum中的下一个变量将被赋值为前一个值+1。

其他回答

用户定义的类型,其值可能为kCircle、kRectangle或koblabespheroid。但是,枚举内部的值(kCircle等)在枚举外部是可见的。记住这一点很重要(int i = kCircle;例如,有效的)。

从Xcode 4.4开始,苹果就建议这样定义枚举:

typedef enum ShapeType : NSUInteger {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

它们还提供了一个方便的宏NS_ENUM:

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

这些定义提供了更强的类型检查和更好的代码补全。我找不到NS_ENUM的官方文档,但你可以在这里观看WWDC 2012会议的“Modern Objective-C”视频。


更新 官方文件的链接在这里。

Enum用于为枚举元素赋值,这在struct中无法完成。因此,每次访问完整变量时,我们可以通过在enum中分配给变量的值来完成。默认情况下,它以0赋值开始,但我们可以为它赋任何值,enum中的下一个变量将被赋值为前一个值+1。

这里声明了三件事:声明了一个匿名枚举类型,将ShapeType声明为该匿名枚举的类型定义,将kCircle、kRectangle和kOblateSpheroid三个名称声明为整型常量。

让我们来分析一下。在最简单的情况下,枚举可以声明为

enum tagname { ... };

这声明了一个带有标记tagname的枚举。在C和Objective-C(但不是c++)中,任何对它的引用都必须在enum关键字之前。例如:

enum tagname x;  // declare x of type 'enum tagname'
tagname x;  // ERROR in C/Objective-C, OK in C++

为了避免必须在所有地方使用enum关键字,可以创建一个typedef:

enum tagname { ... };
typedef enum tagname tagname;  // declare 'tagname' as a typedef for 'enum tagname'

这可以简化成一行:

typedef enum tagname { ... } tagname;  // declare both 'enum tagname' and 'tagname'

最后,如果我们不需要将enum tagname与enum关键字一起使用,我们可以使enum匿名,只使用typedef名称声明它:

typedef enum { ... } tagname;

现在,在本例中,我们将ShapeType声明为匿名枚举的类型定义名称。ShapeType实际上只是一个整型,应该只用于声明包含声明中列出的值之一的变量(即kCircle、kRectangle和kOblateSpheroid之一)。不过,您可以通过强制转换为ShapeType变量分配另一个值,因此在读取enum值时必须小心。

最后,kCircle、kRectangle和kOblateSpheroid在全局命名空间中被声明为整数常量。由于没有指定特定的值,它们被分配给以0开头的连续整数,因此kCircle为0,kRectangle为1,kOblateSpheroid为2。

枚举声明了一组有序值——typedef只是给它加了一个方便的名字。第一个元素是0等等。

typedef enum {
Monday=1,
...
} WORKDAYS;

WORKDAYS today = Monday;

上面只是shapeType标记的枚举。