C
enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;
Declaração que atua como uma definição provisória de um número inteiro assinado s
com tipo completo e declaração que atua como uma definição provisória de um número inteiro assinado q
com tipo incompleto no escopo (que resolve para o tipo completo no escopo porque a definição de tipo está presente em qualquer lugar do escopo) (como qualquer definição provisória, os identificadores q
e s
podem ser redeclarados com a versão incompleta ou completa do mesmo tipo int
ou enum stuff
várias vezes, mas definidos apenas uma vez no escopo, por exemplo, int q = 3; e só podem ser redefinidos em um sub-escopo, e apenas utilizável após a definição). Além disso, você só pode usar o tipo completo de enum stuff
uma vez no escopo porque ele atua como uma definição de tipo.
Uma definição de tipo de enumeração do compilador enum stuff
também é apresentada no escopo do arquivo (utilizável antes e abaixo), bem como uma declaração de tipo encaminhamento (o tipo enum stuff
pode ter várias declarações, mas apenas uma definição / conclusão no escopo e pode ser redefinido em um sub-escopo) . Ele também atua como uma diretiva de compilador para substituir a
com rvalue 0
, b
por -4
, c
com 5
, d
com -2
, e
com -3
, f
com -1
e g
com -2
no escopo atual. As constantes de enumeração agora se aplicam após a definição até a próxima redefinição em uma enumeração diferente que não pode estar no mesmo nível de escopo.
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
O espaço de nome da tag compartilhado por enum, struct e union é separado e deve ser prefixado pelo tipo keyword (enum, struct ou union) em C, ou seja enum a {a} b
, depois , enum a c
deve ser usado e não a c
. Como o espaço para nome da tag é separado do espaço para nome do identificador, enum a {a} b
é permitido, mas enum a {a, b} b
não porque as constantes estão no mesmo espaço para nome dos identificadores da variável, o espaço para nome do identificador.typedef enum a {a,b} b
também não é permitido porque typedef-names fazem parte do espaço para nome do identificador.
O tipo de enum bool
e as constantes seguem o seguinte padrão em 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 |
+-----------+-----+---------------+------+
Isso compila bem em 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 ++
Em C ++, enumerações podem ter um tipo
enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error
Nessa situação, as constantes e o identificador têm o mesmo tipo, bool e um erro ocorrerá se um número não puder ser representado por esse tipo. Talvez = 2, o que não é um bool. Além disso, True, False e Bool não podem estar em minúsculas, caso contrário, entrarão em conflito com as palavras-chave do idioma. Um enum também não pode ter um tipo de ponteiro.
As regras para enumerações são diferentes em 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;
}
Variáveis de enumerações em C ++ não são mais apenas números inteiros não assinados etc., elas também são do tipo enumeração e só podem ser atribuídas constantes na enumeração. No entanto, isso pode ser descartado.
#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
}
Classes Enum
enum struct
é idêntico 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
}
O operador de resolução do escopo ainda pode ser usado para enumerações sem escopo.
#include <stdio.h>
enum a: bool {l, w} ;
int main() {
enum a: bool {w, l} f;
printf("%llu", ::a::w);
}
Mas como w não pode ser definido como outra coisa no escopo, não há diferença entre ::w
e::a::w