C
enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;
Dichiarazione che funge da definizione provvisoria di un numero intero s
con segno con tipo completo e dichiarazione che funge da definizione provvisoria di numero intero q
con segno con tipo incompleto nell'ambito (che si risolve al tipo completo nell'ambito poiché la definizione del tipo è presente ovunque nel ambito) (come qualsiasi definizione provvisoria, gli identificatori q
e s
possono essere ridecressi con la versione incompleta o completa dello stesso tipo int
o enum stuff
più volte ma definiti una sola volta nell'ambito nell'ambito cioè int q = 3; e possono essere ridefiniti solo in un sottoscope e utilizzabile solo dopo la definizione). Inoltre è possibile utilizzare solo il tipo completo dienum stuff
una sola volta nell'ambito poiché funge da definizione del tipo.
Una definizione del tipo di enumerazione del compilatore enum stuff
è resa presente anche nell'ambito del file (utilizzabile prima e sotto) e una dichiarazione del tipo forward (il tipo enum stuff
può avere più dichiarazioni ma solo una definizione / completamento nell'ambito e può essere ridefinito in un sottoscope) . Funge anche da direttiva del compilatore per sostituire a
con rvalue 0
, b
con -4
, c
con 5
, d
con -2
, e
con -3
, f
con -1
e g
con -2
nell'ambito attuale. Le costanti di enumerazione ora si applicano dopo la definizione fino alla ridefinizione successiva in un enum diverso che non può essere sullo stesso livello di ambito.
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
Lo spazio dei nomi dei tag condiviso da enum, struct e union è separato e deve essere preceduto dalla parola chiave type (enum, struct o union) in C, ovvero dopo enum a {a} b
, enum a c
deve essere utilizzato e non a c
. Poiché lo spazio dei nomi dei tag è separato dallo spazio dei nomi dell'identificatore, enum a {a} b
è consentito ma enum a {a, b} b
non perché le costanti si trovano nello stesso spazio dei nomi degli identificatori delle variabili, lo spazio dei nomi dell'identificatore.typedef enum a {a,b} b
inoltre non è consentito perché i nomi typedef fanno parte dello spazio dei nomi identificativo.
Il tipo di enum bool
e le costanti seguono il seguente modello in 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 |
+-----------+-----+---------------+------+
Questo si compila bene in 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 ++
In C ++, gli enum possono avere un tipo
enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error
In questa situazione, le costanti e l'identificatore hanno tutti lo stesso tipo, valore booleano e si verificherà un errore se un numero non può essere rappresentato da quel tipo. Forse = 2, che non è un bool. Inoltre, True, False e Bool non possono essere minuscoli, altrimenti si scontreranno con le parole chiave del linguaggio. Un enum inoltre non può avere un tipo di puntatore.
Le regole per enum sono diverse in 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;
}
Le variabili Enum in C ++ non sono più solo numeri interi senza segno, ecc., Ma sono anche di tipo enum e possono essere assegnate solo costanti nell'enum. Questo può comunque essere gettato via.
#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
}
Classi Enum
enum struct
è identico a 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'operatore di risoluzione dell'ambito può ancora essere utilizzato per enumerazioni senza ambito.
#include <stdio.h>
enum a: bool {l, w} ;
int main() {
enum a: bool {w, l} f;
printf("%llu", ::a::w);
}
Ma poiché w non può essere definito come qualcos'altro nell'ambito, non vi è alcuna differenza tra ::w
e::a::w