No creo que entienda fundamentalmente qué enum
es un y cuándo usarlo.
Por ejemplo:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
¿Qué se declara realmente aquí?
No creo que entienda fundamentalmente qué enum
es un y cuándo usarlo.
Por ejemplo:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
¿Qué se declara realmente aquí?
Respuestas:
Hay tres cosas que les está declarando aquí: un tipo enumerado en el anonimato se declara, ShapeType
se desea declarar un typedef para que la enumeración anónima, y los tres nombres kCircle
, kRectangle
y kOblateSpheroid
se declaran como constantes integrales.
Analicemos eso. En el caso más simple, una enumeración puede declararse como
enum tagname { ... };
Esto declara una enumeración con la etiqueta tagname
. En C y Objective-C (pero no en C ++), cualquier referencia a esto debe ir precedida de la enum
palabra clave. Por ejemplo:
enum tagname x; // declare x of type 'enum tagname'
tagname x; // ERROR in C/Objective-C, OK in C++
Para evitar tener que usar la enum
palabra clave en todas partes, se puede crear un typedef:
enum tagname { ... };
typedef enum tagname tagname; // declare 'tagname' as a typedef for 'enum tagname'
Esto se puede simplificar en una línea:
typedef enum tagname { ... } tagname; // declare both 'enum tagname' and 'tagname'
Y finalmente, si no necesitamos poder usar enum tagname
la enum
palabra clave, podemos hacer el enum
anónimo y solo declararlo con el nombre typedef:
typedef enum { ... } tagname;
Ahora, en este caso, estamos declarando ShapeType
ser un nombre definido por tipo de una enumeración anónima. ShapeType
es en realidad un tipo entero, y sólo debe utilizarse para declarar variables que mantienen uno de los valores que figuran en la declaración (es decir, uno de kCircle
, kRectangle
y kOblateSpheroid
). Sin ShapeType
embargo, puede asignar un valor a una variable mediante conversión, por lo que debe tener cuidado al leer valores de enumeración.
Finalmente, kCircle
, kRectangle
, y kOblateSpheroid
se declaran como constantes integrales en el espacio de nombres global. Como no se especificaron valores específicos, se asignan a enteros consecutivos que comienzan con 0, por lo que kCircle
es 0, kRectangle
es 1 y kOblateSpheroid
es 2.
Apple recomienda definir enumeraciones como esta desde Xcode 4.4 :
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
También proporcionan una práctica macro NS_ENUM
:
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
Estas definiciones proporcionan una verificación de tipo más fuerte y una mejor finalización del código. No pude encontrar la documentación oficial de NS_ENUM
, pero puedes ver el video "Modern Objective-C" de la sesión de WWDC 2012 aquí .
ACTUALIZACIÓN
Enlace a la documentación oficial aquí .
NS_ENUM
macro de Apple por NSHipster: NSHipster.com/ns_enum-ns_options
Un tipo definido por el usuario que tiene los posibles valores de kCircle
, kRectangle
o kOblateSpheroid
. Sin embargo, los valores dentro de la enumeración (kCircle, etc.) son visibles fuera de la enumeración. Es importante tener eso en cuenta ( int i = kCircle;
es válido, por ejemplo).
Actualización para el cambio de 64 bits: según los documentos de Apple sobre los cambios de 64 bits,
Las enumeraciones también se escriben: en el compilador LLVM, los tipos enumerados pueden definir el tamaño de la enumeración. Esto significa que algunos tipos enumerados también pueden tener un tamaño que es más grande de lo esperado. La solución, como en todos los demás casos, es no hacer suposiciones sobre el tamaño de un tipo de datos. En su lugar, asigne cualquier valor enumerado a una variable con el tipo de datos adecuado
Por lo tanto, debe crear una enumeración con el tipo de sintaxis a continuación si admite 64 bits.
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
o
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
De lo contrario, dará lugar a advertencia como Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType
Actualización para programación rápida:
En Swift, hay un cambio de sintaxis.
enum ControlButtonID: NSUInteger {
case kCircle , kRectangle, kOblateSpheroid
}
La enumeración (abreviatura de enumeración) se utiliza para enumerar un conjunto de valores (enumeradores). Un valor es una cosa abstracta representada por un símbolo (una palabra). Por ejemplo, una enumeración básica podría ser
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };
Esta enumeración se llama anónima porque no tiene un símbolo para nombrarla. Pero sigue siendo perfectamente correcto. Solo úsalo así
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
Okay. La vida es bella y todo va bien. Pero un día necesita reutilizar esta enumeración para definir una nueva variable para almacenar myGrandFatherPantSize, luego escribe:
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;
Pero entonces tiene un error de compilación "redefinición de enumerador". En realidad, el problema es que el compilador no está seguro de que primero enumere y que en segundo lugar describa lo mismo.
Luego, si desea reutilizar el mismo conjunto de enumeradores (aquí xs ... xxxxl) en varios lugares, debe etiquetarlo con un nombre único. La segunda vez que use este conjunto, solo tiene que usar la etiqueta. Pero no olvide que esta etiqueta no reemplaza la palabra enum, sino solo el conjunto de enumeradores. Luego tenga cuidado de usar enum como de costumbre. Me gusta esto:
// 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;
también puede usarlo en una definición de parámetro:
// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;
Se podría decir que reescribir la enumeración en todas partes no es conveniente y hace que el código se vea un poco extraño. Tienes razón. Un tipo real sería mejor.
Este es el paso final de nuestra gran progresión hacia la cumbre. Simplemente agregando un typedef, transformemos nuestra enumeración en un tipo real. Oh, lo último, typedef no está permitido dentro de tu clase. Luego defina su tipo justo arriba. Hazlo asi:
// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type
@interface myClass {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
Recuerda que la etiqueta es opcional. Entonces, desde aquí, en ese caso, no etiquetamos los enumeradores, sino solo para definir un nuevo tipo. Entonces ya no lo necesitamos más.
// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;
@interface myClass : NSObject {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
@end
Si está desarrollando en Objective-C con XCode, le dejo descubrir algunas buenas macros con el prefijo NS_ENUM. Eso debería ayudarlo a definir buenas enumeraciones fácilmente y, además, ayudará al analizador estático a realizar algunas comprobaciones interesantes antes de compilar.
Buena enum!
typedef
es útil para redefinir el nombre de un tipo de variable existente. Proporciona una forma breve y significativa de llamar a un tipo de datos. p.ej:
typedef unsigned long int TWOWORDS;
aquí, el tipo unsigned long int se redefine para ser del tipo TWOWORDS. Por lo tanto, ahora podemos declarar variables de tipo unsigned long int escribiendo,
TWOWORDS var1, var2;
en vez de
unsigned long int var1, var2;
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
entonces puedes usarlo como: -
ShapeType shape;
y
enum {
kCircle,
kRectangle,
kOblateSpheroid
}
ShapeType;
ahora puedes usarlo como: -
enum ShapeType shape;
enum se usa para asignar valor a elementos enum que no se pueden hacer en struct. Entonces, en lugar de acceder a la variable completa, podemos hacerlo por el valor que asignamos a las variables enum. Por defecto, comienza con la asignación 0, pero podemos asignarle cualquier valor y la siguiente variable en enum se le asignará un valor al valor anterior +1.
Puede usar en el siguiente formato, valor predeterminado sin formato a partir de 0, así
Puede asignar su propio valor de inicio específico.
typedef enum : NSUInteger {
kCircle, // for your value; kCircle = 5, ...
kRectangle,
kOblateSpheroid
} ShapeType;
ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0
Un typedef le permite al programador definir un tipo Objective-C como otro. Por ejemplo,
typedef int Counter; define el tipo Counter para que sea equivalente al tipo int. Esto mejora drásticamente la legibilidad del código.
Typedef es una palabra clave en C y C ++. Se utiliza para crear nuevos nombres para los tipos de datos básicos (char, int, float, double, struct & enum) .
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Aquí crea el tipo de datos enumerados ShapeType y podemos escribir nuevos nombres para el tipo de enumeración ShapeType como se indica a continuación
ShapeType shape1;
ShapeType shape2;
ShapeType shape3;
enum puede reducir muchos tipos de "errores" y hacer que el código sea más manejable
#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER
La definición no tiene restricciones. Es simplemente una sustitución. No puede limitar todas las condiciones del estado. Cuando el ESTADO se asigna a 5, el programa se equivocará porque no hay un estado coincidente. Pero el compilador no va a advertir ESTADO = 5
Entonces es mejor usarlo así
typedef enum SampleState {
SampleStateGood = 0,
SampleStateBad,
SampleStateOther
} SampleState;
SampleState state = SampleStateGood;