Je ne pense pas que je comprends fondamentalement ce qu'est un enum
, et quand l'utiliser.
Par exemple:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Qu'est-ce qui est vraiment déclaré ici?
Je ne pense pas que je comprends fondamentalement ce qu'est un enum
, et quand l'utiliser.
Par exemple:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Qu'est-ce qui est vraiment déclaré ici?
Réponses:
Trois choses sont déclarées ici: un type anonyme est recensée déclaré, ShapeType
est d' être déclaré typedef pour cette énumération anonyme, et les trois noms kCircle
, kRectangle
et kOblateSpheroid
sont déclarées comme constantes intégrales.
Décomposons cela. Dans le cas le plus simple, une énumération peut être déclarée comme
enum tagname { ... };
Cela déclare une énumération avec la balise tagname
. En C et Objective-C (mais pas C ++), toute référence à cela doit être précédée du enum
mot - clé. Par exemple:
enum tagname x; // declare x of type 'enum tagname'
tagname x; // ERROR in C/Objective-C, OK in C++
Afin d'éviter d'avoir à utiliser le enum
mot - clé partout, un typedef peut être créé:
enum tagname { ... };
typedef enum tagname tagname; // declare 'tagname' as a typedef for 'enum tagname'
Cela peut être simplifié en une seule ligne:
typedef enum tagname { ... } tagname; // declare both 'enum tagname' and 'tagname'
Et enfin, si nous n'avons pas besoin de pouvoir l'utiliser enum tagname
avec le enum
mot - clé, nous pouvons faire l' enum
anonymat et le déclarer uniquement avec le nom typedef:
typedef enum { ... } tagname;
Maintenant, dans ce cas, nous ShapeType
déclarons être le nom typé d'une énumération anonyme. ShapeType
est vraiment juste un type intégral, et ne doit être utilisé pour déclarer des variables qui détiennent l' une des valeurs énumérées dans la déclaration (qui est, l' un des kCircle
, kRectangle
et kOblateSpheroid
). Vous pouvez cependant attribuer une ShapeType
variable à une variable en effectuant un cast, vous devez donc être prudent lors de la lecture des valeurs d'énumération.
Enfin, kCircle
, kRectangle
et kOblateSpheroid
sont déclarées comme constantes intégrées dans l'espace de noms global. Puisqu'aucune valeur spécifique n'a été spécifiée, elles sont affectées à des entiers consécutifs commençant par 0, donc kCircle
0, kRectangle
1 et kOblateSpheroid
2.
Apple recommande de définir des énumérations comme celle-ci depuis Xcode 4.4 :
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Ils fournissent également une macro pratique NS_ENUM
:
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
Ces définitions fournissent une vérification de type plus forte et une meilleure exécution du code. Je n'ai pas pu trouver la documentation officielle de NS_ENUM
, mais vous pouvez regarder la vidéo "Modern Objective-C" de la session WWDC 2012 ici .
UPDATE
Lien vers la documentation officielle ici .
NS_ENUM
macro d'Apple par NSHipster: NSHipster.com/ns_enum-ns_options
Un utilisateur type défini qui a les valeurs possibles kCircle
, kRectangle
ou kOblateSpheroid
. Les valeurs à l'intérieur de l'énumération (kCircle, etc.) sont cependant visibles à l'extérieur de l'énumération. Il est important de garder cela à l'esprit ( int i = kCircle;
est valable, par exemple).
Mise à jour pour la modification 64 bits: selon les documents Apple concernant les modifications 64 bits,
Les énumérations sont également typées: dans le compilateur LLVM, les types énumérés peuvent définir la taille de l'énumération. Cela signifie que certains types énumérés peuvent également avoir une taille supérieure à ce que vous attendez. La solution, comme dans tous les autres cas, est de ne faire aucune hypothèse sur la taille d'un type de données. Au lieu de cela, affectez toutes les valeurs énumérées à une variable avec le type de données approprié
Vous devez donc créer une énumération avec le type comme syntaxe ci-dessous si vous prenez en charge 64 bits.
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
ou
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Sinon, cela conduira à un avertissement Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType
Mise à jour pour la programmation rapide:
Dans swift, il y a un changement de syntaxe.
enum ControlButtonID: NSUInteger {
case kCircle , kRectangle, kOblateSpheroid
}
L'énumération (abréviation d'énumération) est utilisée pour énumérer un ensemble de valeurs (énumérateurs). Une valeur est une chose abstraite représentée par un symbole (un mot). Par exemple, une énumération de base peut être
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };
Cette énumération est appelée anonyme car vous n'avez pas de symbole pour la nommer. Mais c'est toujours parfaitement correct. Il suffit de l'utiliser comme ça
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
D'accord. La vie est belle et tout se passe bien. Mais un jour, vous devez réutiliser cette énumération pour définir une nouvelle variable pour stocker myGrandFatherPantSize, puis vous écrivez:
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;
Mais alors vous avez une erreur de compilation "redéfinition de l'énumérateur". En fait, le problème est que le compilateur n'est pas sûr que vous énumérez d'abord et que vous décrivez ensuite la même chose.
Ensuite, si vous souhaitez réutiliser le même ensemble d'énumérateurs (ici xs ... xxxxl) à plusieurs endroits, vous devez le marquer avec un nom unique. La deuxième fois que vous utilisez cet ensemble, vous n'avez qu'à utiliser la balise. Mais n'oubliez pas que cette balise ne remplace pas le mot enum mais juste l'ensemble des énumérateurs. Veillez ensuite à utiliser enum comme d'habitude. Comme ça:
// 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;
vous pouvez également l'utiliser dans une définition de paramètre:
// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;
On pourrait dire que réécrire enum partout n'est pas pratique et rend le code un peu étrange. Tu as raison. Un vrai type serait mieux.
Il s'agit de l'ultime étape de notre grande progression vers le sommet. En ajoutant simplement un typedef, transformons notre énumération en un vrai type. Oh la dernière chose, typedef n'est pas autorisé dans votre classe. Définissez ensuite votre type juste au-dessus. Fais-le comme ça:
// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type
@interface myClass {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
N'oubliez pas que la balise est facultative. Alors qu'ici, dans ce cas, nous ne marquons pas les énumérateurs mais juste pour définir un nouveau type. Ensuite, nous n'en avons plus vraiment besoin.
// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;
@interface myClass : NSObject {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
@end
Si vous développez en Objective-C avec XCode, je vous laisse découvrir de belles macros préfixées avec NS_ENUM. Cela devrait vous aider à définir facilement de bonnes énumérations et aidera l'analyseur statique à effectuer des vérifications intéressantes pour vous avant de compiler.
Bon Enum!
typedef
est utile pour redéfinir le nom d'un type de variable existant. Il fournit un moyen court et significatif d'appeler un type de données. par exemple:
typedef unsigned long int TWOWORDS;
ici, le type unsigned long int est redéfini pour être du type TWOWORDS. Ainsi, nous pouvons maintenant déclarer des variables de type non signé long int en écrivant,
TWOWORDS var1, var2;
au lieu de
unsigned long int var1, var2;
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
alors vous pouvez l'utiliser comme: -
ShapeType shape;
et
enum {
kCircle,
kRectangle,
kOblateSpheroid
}
ShapeType;
maintenant vous pouvez l'utiliser comme: -
enum ShapeType shape;
enum est utilisé pour assigner une valeur aux éléments enum qui ne peuvent pas être faits dans struct. Donc, à chaque fois au lieu d'accéder à la variable complète, nous pouvons le faire par la valeur que nous attribuons aux variables enum. Par défaut, il commence par une affectation de 0, mais nous pouvons lui attribuer n'importe quelle valeur et la variable suivante enum recevra une valeur la valeur précédente +1.
Vous pouvez utiliser dans le format ci-dessous, la valeur par défaut brute à partir de 0, donc
Vous pouvez attribuer votre propre valeur de départ spécifique.
typedef enum : NSUInteger {
kCircle, // for your value; kCircle = 5, ...
kRectangle,
kOblateSpheroid
} ShapeType;
ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0
Un typedef permet au programmeur de définir un type Objective-C comme un autre. Par exemple,
typedef int Counter; définit le type Counter comme équivalent au type int. Cela améliore considérablement la lisibilité du code.
Le Typedef est un mot-clé en C et C ++. Il est utilisé pour créer de nouveaux noms pour les types de données de base (char, int, float, double, struct & enum) .
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Ici, il crée le type de données énuméré ShapeType et nous pouvons écrire de nouveaux noms pour le type enum ShapeType comme indiqué ci-dessous
ShapeType shape1;
ShapeType shape2;
ShapeType shape3;
enum peut réduire de nombreux types d'erreurs et rendre le code plus facile à gérer
#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER
La définition n'a pas de contraintes. C'est simplement une substitution. Il n'est pas en mesure de limiter toutes les conditions de l'État. Lorsque l'état est affecté à 5, le programme sera erroné, car il n'y a pas d'état correspondant. Mais le compilateur ne va pas avertir STATE = 5
Il vaut donc mieux utiliser comme ça
typedef enum SampleState {
SampleStateGood = 0,
SampleStateBad,
SampleStateOther
} SampleState;
SampleState state = SampleStateGood;