C
enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;
Declaración que actúa como una definición tentativa de un número entero s
con signo con tipo completo y declaración que actúa como una definición tentativa de número entero q
con signo con tipo incompleto en el ámbito (que resuelve el tipo completo en el ámbito porque la definición de tipo está presente en cualquier lugar del alcance) (como cualquier definición tentativa, los identificadores q
y se s
pueden volver a declarar con la versión incompleta o completa del mismo tipo int
o enum stuff
varias veces, pero solo se definen una vez en el alcance, es decir, int q = 3; y solo se pueden redefinir en un subscopio, y solo utilizable después de la definición). Además, solo puede usar el tipo completo deenum stuff
una vez en el ámbito porque actúa como una definición de tipo.
Una definición de tipo de enumeración del compilador enum stuff
también se hace presente en el alcance del archivo (utilizable antes y a continuación), así como una declaración de tipo de reenvío (el tipo enum stuff
puede tener múltiples declaraciones pero solo una definición / finalización en el alcance y puede redefinirse en un subscopio) . También actúa como directiva compiladora para sustituir a
con rvalue 0
, b
with -4
, c
with 5
, d
with -2
, e
with -3
, f
with -1
y g
with -2
en el ámbito actual. Las constantes de enumeración ahora se aplican después de la definición hasta la próxima redefinición en una enumeración diferente que no puede estar en el mismo nivel de alcance.
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
El espacio de nombres de etiqueta compartido por enum, struct y union está separado y debe tener el prefijo de la palabra clave type (enum, struct o union) en C, es decir enum a {a} b
, después enum a c
debe usarse y no a c
. Debido a que el espacio de nombres de la etiqueta está separado del espacio de nombres del identificador, enum a {a} b
está permitido pero enum a {a, b} b
no porque las constantes estén en el mismo espacio de nombres que los identificadores variables, el espacio de nombres del identificador. typedef enum a {a,b} b
tampoco está permitido porque typedef-names son parte del espacio de nombres del identificador.
El tipo de enum bool
y las constantes siguen el siguiente patrón 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 |
+-----------+-----+---------------+------+
Esto compila 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 ++, las enumeraciones pueden tener un tipo
enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error
En esta situación, las constantes y el identificador tienen el mismo tipo, bool, y se producirá un error si un número no puede ser representado por ese tipo. Quizás = 2, que no es un bool. Además, Verdadero, Falso y Bool no pueden ser minúsculas, de lo contrario chocarán con las palabras clave del idioma. Una enumeración tampoco puede tener un tipo de puntero.
Las reglas para las enumeraciones son diferentes 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;
}
Las variables de enumeración en C ++ ya no son solo enteros sin signo, etc., también son de tipo enumeración y solo se les pueden asignar constantes en la enumeración. Sin embargo, esto puede descartarse.
#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
}
Clases de enumeración
enum struct
es 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
}
El operador de resolución de alcance todavía se puede usar para enumeraciones sin ámbito.
#include <stdio.h>
enum a: bool {l, w} ;
int main() {
enum a: bool {w, l} f;
printf("%llu", ::a::w);
}
Pero debido a que w no puede definirse como algo más en el alcance, no hay diferencia entre ::w
y::a::w