我认为我从根本上不了解enum
是什么,以及何时使用它。
例如:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
这里真正宣布了什么?
答案 0 :(得分:1553)
这里声明了三件事:声明了一个匿名枚举类型,ShapeType
被声明为该匿名枚举的typedef,以及三个名称kCircle
,kRectangle
和{ {1}}被声明为整数常量。
让我们打破它。在最简单的情况下,枚举可以声明为
kOblateSpheroid
这声明了一个带有标记enum tagname { ... };
的枚举。在C和Objective-C(但不是 C ++)中,对此的任何引用都必须以tagname
关键字开头。例如:
enum
为了避免在任何地方使用enum tagname x; // declare x of type 'enum tagname'
tagname x; // ERROR in C/Objective-C, OK in C++
关键字,可以创建typedef:
enum
这可以简化为一行:
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
匿名,并仅使用typedef名称声明它:
enum
现在,在这种情况下,我们声明typedef enum { ... } tagname;
是匿名枚举的typedef名称。 ShapeType
实际上只是一个整数类型,并且只应用于声明包含声明中列出的值之一的变量(即ShapeType
,kCircle
和{{}之一{1}})。但是,您可以通过强制转换为kRectangle
变量分配另一个值,因此在读取枚举值时必须小心。
最后,kOblateSpheroid
,ShapeType
和kCircle
在全局命名空间中被声明为整数常量。由于未指定特定值,因此将它们分配给从0开始的连续整数,因此kRectangle
为0,kOblateSpheroid
为1,kCircle
为2。
答案 1 :(得分:251)
Apple建议自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会话here中的“Modern Objective-C”视频。
更新:链接到官方文档here。
答案 2 :(得分:51)
枚举声明了一组有序值 - typedef只是为此添加了一个方便的名称。第一个元素是0等。
typedef enum {
Monday=1,
...
} WORKDAYS;
WORKDAYS today = Monday;
以上只是shapeType标签的枚举。
答案 3 :(得分:34)
用户定义的类型,其可能值为kCircle
,kRectangle
或kOblateSpheroid
。但是枚举中的值(kCircle等)在枚举之外是可见的。记住这一点很重要(例如int i = kCircle;
是有效的。)
答案 4 :(得分:29)
更新64位更改: 根据{{3}}大约64位的变化,
还输入枚举:在LLVM编译器中,枚举类型可以 定义枚举的大小。这意味着一些枚举 类型的大小也可能比您预期的大。该 与所有其他情况一样,解决方案是不做任何关于a的假设 数据类型的大小。而是将任何枚举值分配给变量 使用适当的数据类型
如果您支持64位,则必须使用类型创建枚举,如下所示。
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
或
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
否则,它将导致警告Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType
swift-programming更新:
在swift中,语法发生了变化。
enum ControlButtonID: NSUInteger {
case kCircle , kRectangle, kOblateSpheroid
}
答案 5 :(得分:24)
枚举(枚举的缩写)用于枚举一组值(枚举器)。值是由符号(单词)表示的抽象事物。 例如,基本枚举可以是
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };
此枚举称为匿名,因为您没有用于命名的符号。但它仍然是完全正确的。就这样使用它
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
确定。生活很美好,一切顺利。但有一天你需要重用这个枚举来定义一个新变量来存储myGrandFatherPantSize,然后你写:
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;
但是你有一个编译器错误“重新定义枚举器”。实际上,问题是编译器不确定你是第一次枚举而你是第二次描述同样的事情。
然后,如果要在多个位置重复使用同一组枚举器(此处为xs ... xxxxl),则必须使用唯一名称对其进行标记。第二次使用此设置时,您只需使用标签。但是不要忘记这个标签不会取代枚举词,而只会取代枚举器集。然后像往常一样注意使用枚举。像这样:
// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
// here the second use of my enum. It works now!
enum sizes myGrandFatherPantSize;
您也可以在参数定义中使用它:
// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;
你可以说在任何地方重写枚举都不方便,并且使代码看起来有点奇怪。你是对的。真实的类型会更好。
这是我们进入峰会的最后一步。通过添加一个typedef,让我们将enum转换为真实类型。哦,最后一件事,你的班级不允许使用typedef。然后在上面定义您的类型。这样做:
// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type
@interface myClass {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
请记住,标签是可选的。那么从这里开始,在这种情况下,我们不会标记枚举数,只是为了定义一个新类型。那我们就不再需要它了。
// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;
@interface myClass : NSObject {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
@end
如果您使用XCode在Objective-C中进行开发,我会让您发现一些以NS_ENUM为前缀的漂亮宏。这应该可以帮助您轻松定义好的枚举,而且还有助于静态分析器在编译之前为您做一些有趣的检查。
Good Enum!
答案 6 :(得分:10)
typedef
对于重新定义现有变量类型的名称很有用。它提供简短的&调用数据类型的有意义的方法。
e.g:
typedef unsigned long int TWOWORDS;
这里,unsigned long int类型被重新定义为TWOWORDS类型。因此,我们现在可以通过写入
来声明unsigned long int类型的变量TWOWORDS var1, var2;
而不是
unsigned long int var1, var2;
答案 7 :(得分:7)
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
然后您可以使用它: -
ShapeType shape;
和
enum {
kCircle,
kRectangle,
kOblateSpheroid
}
ShapeType;
现在您可以像以下一样使用它: -
enum ShapeType shape;
答案 8 :(得分:3)
枚举用于为枚举元素赋值,这些元素无法在struct中完成。因此,每次都可以通过我们分配给枚举中的变量的值来代替访问完整变量。默认情况下,它以0分配开始,但我们可以为其分配任何值,枚举中的下一个变量将被赋值为前一个值+1。
答案 9 :(得分:2)
typedef允许程序员将一个Objective-C类型定义为另一个。例如,
typedef int Counter;将类型Counter定义为等效于int类型。这大大提高了代码的可读性。
答案 10 :(得分:2)
Typedef是C和C ++中的关键字。它用于为基本数据类型(char,int,float,double,struct& enum)创建新名称。
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
这里创建枚举数据类型 ShapeType &我们可以为枚举类型 ShapeType 编写新名称,如下所示
ShapeType shape1;
ShapeType shape2;
ShapeType shape3;
答案 11 :(得分:2)
您可以使用以下格式,Raw默认值从0开始,所以
您可以指定自己的特定起始值。
{{1}}
答案 12 :(得分:0)
枚举可以减少许多类型的“错误”,并使代码更易于管理
#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER
该定义没有约束。这仅仅是替代。 它不能限制状态的所有条件。将STATE分配给5时,程序将出错,因为没有匹配的状态。但是编译器不会警告STATE = 5
所以最好像这样使用
typedef enum SampleState {
SampleStateGood = 0,
SampleStateBad,
SampleStateOther
} SampleState;
SampleState state = SampleStateGood;