C
enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;
Déclaration qui agit comme une définition provisoire d'un entier signé s
avec un type complet et déclaration qui agit comme une définition provisoire d'un entier signé q
avec un type incomplet dans la portée (qui se résout en type complet dans la portée car la définition de type est présente n'importe où dans le portée) (comme toute définition provisoire, les identifiants q
et s
peuvent être redéclarés avec la version incomplète ou complète du même type int
ou enum stuff
plusieurs fois mais définis une seule fois dans la portée, c'est-à-dire int q = 3; et ne peuvent être redéfinis que dans une sous-portée, et utilisable uniquement après la définition). De plus, vous ne pouvez utiliser le type complet enum stuff
qu'une fois dans la portée, car il agit comme une définition de type.
Une définition de type d'énumération du compilateur pour enum stuff
est également présente dans la portée du fichier (utilisable avant et ci-dessous) ainsi qu'une déclaration de type avant (le type enum stuff
peut avoir plusieurs déclarations mais une seule définition / complétion dans la portée et peut être redéfini dans une sous-portée) . Il agit également comme une directive de compilation pour remplacer a
rvalue 0
, b
with -4
, c
with 5
, d
with -2
, e
with -3
, f
with -1
et g
with -2
dans la portée actuelle. Les constantes d'énumération s'appliquent désormais après la définition jusqu'à la redéfinition suivante dans une énumération différente qui ne peut pas être au même niveau de portée.
typedef enum bool {false, true} bool;
//this is the same as
enum bool {false, true};
typedef enum bool bool;
//or
enum bool {false, true};
typedef unsigned int bool;
//remember though, bool is an alias for _Bool if you include stdbool.h.
//and casting to a bool is the same as the !! operator
L'espace de noms de balise partagé par enum, struct et union est séparé et doit être préfixé par le mot-clé type (enum, struct ou union) en C c'est-à-dire après enum a {a} b
, enum a c
doit être utilisé et non a c
. Étant donné que l'espace de noms des balises est distinct de l'espace de noms des identificateurs, il enum a {a} b
est autorisé mais enum a {a, b} b
pas parce que les constantes se trouvent dans le même espace de noms que les identificateurs de variables, l'espace de noms des identificateurs. typedef enum a {a,b} b
n'est pas non plus autorisé car les noms de typedef font partie de l'espace de noms des identifiants.
Le type de enum bool
et les constantes suivent le modèle suivant en C:
+--------------+-----+-----+-----+
| enum bool | a=1 |b='a'| c=3 |
+--------------+-----+-----+-----+
| unsigned int | int | int | int |
+--------------+-----+-----+-----+
+--------------+-----+-----+-----+
| enum bool | a=1 | b=-2| c=3 |
+--------------+-----+-----+-----+
| int | int | int | int |
+--------------+-----+-----+-----+
+--------------+-----+---------------+-----+
| enum bool | a=1 |b=(-)0x80000000| c=2 |
+--------------+-----+---------------+-----+
| unsigned int | int | unsigned int | int |
+--------------+-----+---------------+-----+
+--------------+-----+---------------+-----+
| enum bool | a=1 |b=(-)2147483648| c=2 |
+--------------+-----+---------------+-----+
| unsigned int | int | unsigned int | int |
+--------------+-----+---------------+-----+
+-----------+-----+---------------+------+
| enum bool | a=1 |b=(-)0x80000000| c=-2 |
+-----------+-----+---------------+------+
| long | int | long | int |
+-----------+-----+---------------+------+
+-----------+-----+---------------+------+
| enum bool | a=1 | b=2147483648 | c=-2 |
+-----------+-----+---------------+------+
| long | int | long | int |
+-----------+-----+---------------+------+
+-----------+-----+---------------+------+
| enum bool | a=1 | b=-2147483648 | c=-2 |
+-----------+-----+---------------+------+
| int | int | int | int |
+-----------+-----+---------------+------+
+---------------+-----+---------------+-----+
| enum bool | a=1 | b=99999999999 | c=1 |
+---------------+-----+---------------+-----+
| unsigned long | int | unsigned long | int |
+---------------+-----+---------------+-----+
+-----------+-----+---------------+------+
| enum bool | a=1 | b=99999999999 | c=-1 |
+-----------+-----+---------------+------+
| long | int | long | int |
+-----------+-----+---------------+------+
Cela compile bien en C:
#include <stdio.h>
enum c j;
enum c{f, m} p;
typedef int d;
typedef int c;
enum c j;
enum m {n} ;
int main() {
enum c j;
enum d{l};
enum d q;
enum m y;
printf("%llu", j);
}
C ++
En C ++, les énumérations peuvent avoir un type
enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error
Dans cette situation, les constantes et l'identifiant ont tous le même type, bool, et une erreur se produira si un nombre ne peut pas être représenté par ce type. Peut-être = 2, ce qui n'est pas un bool. De plus, True, False et Bool ne peuvent pas être en minuscules, sinon ils se heurteront aux mots-clés de langue. Une énumération ne peut pas non plus avoir de type pointeur.
Les règles pour les énumérations sont différentes en C ++.
#include <iostream>
c j; //not allowed, unknown type name c before enum c{f} p; line
enum c j; //not allowed, forward declaration of enum type not allowed and variable can have an incomplete type but not when it's still a forward declaration in C++ unlike C
enum c{f, m} p;
typedef int d;
typedef int c; // not allowed in C++ as it clashes with enum c, but if just int c were used then the below usages of c j; would have to be enum c j;
[enum] c j;
enum m {n} ;
int main() {
[enum] c j;
enum d{l}; //not allowed in same scope as typedef but allowed here
d q;
m y; //simple type specifier not allowed, need elaborated type specifier enum m to refer to enum m here
p v; // not allowed, need enum p to refer to enum p
std::cout << j;
}
Les variables enums en C ++ ne sont plus seulement des entiers non signés, etc., elles sont également de type enum et ne peuvent être affectées qu'à des constantes dans l'énumération. Cela peut cependant être rejeté.
#include <stdio.h>
enum a {l} c;
enum d {f} ;
int main() {
c=0; // not allowed;
c=l;
c=(a)1;
c=(enum a)4;
printf("%llu", c); //4
}
Enum classes
enum struct
est identique à enum class
#include <stdio.h>
enum class a {b} c;
int main() {
printf("%llu", a::b<1) ; //not allowed
printf("%llu", (int)a::b<1) ;
printf("%llu", a::b<(a)1) ;
printf("%llu", a::b<(enum a)1);
printf("%llu", a::b<(enum class a)1) ; //not allowed
printf("%llu", b<(enum a)1); //not allowed
}
L'opérateur de résolution de portée peut toujours être utilisé pour les énumérations non étendues.
#include <stdio.h>
enum a: bool {l, w} ;
int main() {
enum a: bool {w, l} f;
printf("%llu", ::a::w);
}
Mais parce que w ne peut pas être défini comme autre chose dans la portée, il n'y a pas de différence entre ::w
et::a::w