enum c enums

enum c++



¿Cómo definir un tipo enumerado(enum) en C? (12)

No estoy seguro de cuál es la sintaxis adecuada para usar C enums. Tengo el siguiente código:

enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE;

Pero esto no se compila, con el siguiente error:

error: conflicting types for ‘strategy’ error: previous declaration of ‘strategy’ was here

¿Qué estoy haciendo mal?


@ThoAppelsin en su comentario a la pregunta publicada es correcto. El fragmento de código publicado en la pregunta es válido y sin errores. El error que tiene debe ser debido a otra sintaxis incorrecta en cualquier otro lugar de su archivo fuente c. enum{a,b,c}; define tres constantes simbólicas ( a , c ) que son enteros con valores 0 , 1 y 2 respectivamente, pero cuando usamos enum es porque generalmente no nos importa el valor entero específico, nos importa más el significado de El nombre de la constante simbólica. Esto significa que puedes tener esto:

#include <stdio.h> enum {a,b,c}; int main(){ printf("%d/n",b); return 0; }

y esto dará salida a 1 .

Esto también será válido:

#include <stdio.h> enum {a,b,c}; int bb=b; int main(){ printf("%d/n",bb); return 0; }

y saldrá lo mismo que antes.

Si haces esto:

enum {a,b,c}; enum {a,b,c};

Tendrás un error, pero si haces esto:

enum alfa{a,b,c}; enum alfa;

no tendras ningun error

Puedes hacerlo:

enum {a,b,c}; int aa=a;

y aa será una variable entera con valor 0 . pero también puedes hacer esto:

enum {a,b,c} aa= a;

y tendrá el mismo efecto (es decir, aa es un int con valor 0 ).

También puedes hacer esto:

enum {a,b,c} aa= a; aa= 7;

y aa será int con valor 7 .

porque no puede repetir la definición de la constante simbólica con el uso de enum , como he dicho anteriormente, debe usar etiquetas si desea declarar int vars con el uso de enum :

enum tag1 {a,b,c}; enum tag1 var1= a; enum tag1 var2= b;

el uso de typedef es para enum tag1 que escriba cada vez que enum tag1 para definir la variable. Con typedef puedes teclear Tag1 :

typedef enum {a,b,c} Tag1; Tag1 var1= a; Tag1 var2= b;

También puedes tener:

typedef enum tag1{a,b,c}Tag1; Tag1 var1= a; enum tag1 var2= b;

Lo último que hay que decir es que, dado que estamos hablando de constantes simbólicas definidas, es mejor usar letras mayúsculas cuando se usa enum , por ejemplo:

enum {A,B,C};

en lugar de

enum {a,b,c};


Como está escrito, no hay nada de malo en su código. ¿Seguro que no has hecho algo así?

int strategy; ... enum {RANDOM, IMMEDIATE, SEARCH} strategy;

¿A qué líneas apuntan los mensajes de error? Cuando dice "la declaración anterior de ''estrategia'' estaba aquí", ¿qué es "aquí" y qué muestra?


Cuando tu dices

enum {RANDOM, IMMEDIATE, SEARCH} strategy;

creas una variable de instancia única, llamada ''estrategia'' de una enumeración sin nombre. Esto no es una cosa muy útil que hacer, necesita un typedef:

typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType; StrategyType strategy = IMMEDIATE;


Estás intentando declarar la strategy dos veces, y es por eso que obtienes el error anterior. Lo siguiente funciona sin ninguna queja (compilado con gcc -ansi -pendantic -Wall ):

#include <stdio.h> enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE; int main(int argc, char** argv){ printf("strategy: %d/n", strategy); return 0; }

Si en lugar de lo anterior, la segunda línea se cambió a:

... enum { RANDOM, IMMEDIATE, SEARCH } strategy; strategy = IMMEDIATE; ...

De las advertencias, usted podría ver fácilmente su error:

enums.c:5:1: warning: data definition has no type or storage class [enabled by default] enums.c:5:1: warning: type defaults to ‘int’ in declaration of ‘strategy’ [-Wimplicit-int] enums.c:5:1: error: conflicting types for ‘strategy’ enums.c:4:36: note: previous declaration of ‘strategy’ was here

Entonces el compilador tomó la strategy = IMMEDIATE para una declaración de una variable llamada strategy con el tipo predeterminado int , pero ya había una declaración previa de una variable con este nombre.

Sin embargo, si coloca la asignación en la función main() , sería un código válido:

#include <stdio.h> enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE; int main(int argc, char** argv){ strategy=SEARCH; printf("strategy: %d/n", strategy); return 0; }


Intenté con gcc y encontré mi necesidad. Me vi obligado a usar la última alternativa, para compilar sin error.

typedef enum state {a = 0, b = 1, c = 2} state ;

typedef enum state {a = 0, b = 1, c = 2} state; typedef enum state old; // New type, alias of the state type. typedef enum state new; // New type, alias of the state type. new now = a; old before = b; printf("State now = %d /n", now); printf("Sate before = %d /n/n", before);


La declaración de una variable enum se hace de la siguiente manera:

enum strategy {RANDOM, IMMEDIATE, SEARCH}; enum strategy my_strategy = IMMEDIATE;

Sin embargo, puede usar typedef para acortar las declaraciones de variables, de esta manera:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy my_strategy = IMMEDIATE;

Tener una convención de nomenclatura para distinguir entre tipos y variables es una buena idea:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type; strategy_type my_strategy = IMMEDIATE;


La respuesta de Tarc es la mejor.

Gran parte de la discusión enumeración es una pista falsa.

Compare este fragmento de código: -

int strategy; strategy = 1; void some_function(void) { }

lo que da

error C2501: ''strategy'' : missing storage-class or type specifiers error C2086: ''strategy'' : redefinition

con éste que compila sin ningún problema.

int strategy; void some_function(void) { strategy = 1; }

La strategy variable debe establecerse en la declaración o dentro de una función, etc. No puede escribir software arbitrario, en particular asignaciones, en el ámbito global.

El hecho de que usara enumeración {RANDOM, INMEDIATE, SEARCH} en lugar de int solo es relevante en la medida en que ha confundido a las personas que no pueden ver más allá. Los mensajes de error de redefinición en la pregunta muestran que esto es lo que el autor ha hecho mal.

Así que ahora debería poder ver por qué el primero del siguiente ejemplo es incorrecto y los otros tres están bien.

Ejemplo 1. ¡INCORRECTO!

enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; void some_function(void) { }

Ejemplo 2. DERECHO.

enum {RANDOM, IMMEDIATE, SEARCH} strategy = IMMEDIATE; void some_function(void) { }

Ejemplo 3. DERECHO.

enum {RANDOM, IMMEDIATE, SEARCH} strategy; void some_function(void) { strategy = IMMEDIATE; }

Ejemplo 4. DERECHO.

void some_function(void) { enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE; }

Si tiene un programa en funcionamiento, debería poder pegar estos fragmentos en su programa y ver que algunos compilan y otros no.


Mi construcción favorita y solo utilizada siempre fue:

typedef enum MyBestEnum { / * suficientemente bueno * / GOOD = 0, /* even better */ BETTER, /* divine */ BEST };

Creo que esto eliminará tu problema que tienes.


Parece que hay una confusión acerca de la declaración.

Cuando la strategy aparece antes de {RANDOM, IMMEDIATE, SEARCH} como en la siguiente,

enum strategy {RANDOM, IMMEDIATE, SEARCH};

usted está creando un nuevo tipo llamado enum strategy . Sin embargo, al declarar la variable, es necesario utilizar la propia enum strategy . No puedes simplemente usar la strategy . Así que lo siguiente no es válido.

enum strategy {RANDOM, IMMEDIATE, SEARCH}; strategy a;

Mientras, lo siguiente es válido

enum strategy {RANDOM, IMMEDIATE, SEARCH}; enum strategy queen = RANDOM; enum strategy king = SEARCH; enum strategy pawn[100];

Cuando la strategy aparece después de {RANDOM, IMMEDIATE, SEARCH} , está creando una enumeración anónima y luego declara que la strategy es una variable de ese tipo.

Así que ahora, puedes hacer algo como

enum {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = RANDOM;

Sin embargo, no puede declarar ninguna otra variable de tipo enum {RANDOM, IMMEDIATE, SEARCH} porque nunca la ha nombrado. Así que lo siguiente no es válido

enum {RANDOM, IMMEDIATE, SEARCH} strategy; enum strategy a = RANDOM;

Puedes combinar ambas definiciones también

enum strategy {RANDOM, IMMEDIATE, SEARCH} a, b; a = RANDOM; b = SEARCH; enum strategy c = IMMEDIATE;

Typedef como se indicó anteriormente se usa para crear una declaración de variable más corta.

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;

Ahora le ha dicho al compilador que la enum {RANDOM, IMMEDIATE, SEARCH} es sinónimo de strategy . Así que ahora puedes usar libremente la strategy como tipo variable. Ya no necesitas escribir la enum strategy . Lo siguiente es válido ahora

strategy x = RANDOM;

También puede combinar Typedef junto con el nombre de enumeración para obtener

typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;

No hay mucha ventaja de usar este método, aparte del hecho de que ahora puede usar la strategy y la enum strategyName intercambiable.

typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy; enum strategyName a = RANDOM; strategy b = SEARCH;


Si declara el nombre para la enumeración, no se producirá ningún error.

Si no se declara, tienes que usar un typedef :

enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy; strategy = IMMEDIATE;

No mostrará un error ...


Vale la pena mencionar que en C ++ puede usar "enum" para definir un nuevo tipo sin necesidad de una declaración typedef.

enum Strategy {RANDOM, IMMEDIATE, SEARCH}; ... Strategy myStrategy = IMMEDIATE;

Encuentro este enfoque mucho más amigable.

[Editar - Aclaré el estado de C ++ - ¡Tuve esto originalmente, luego lo quité!]


Vale la pena señalar que no necesita una typedef . Puedes hacerlo como el siguiente

enum strategy { RANDOM, IMMEDIATE, SEARCH }; enum strategy my_strategy = IMMEDIATE;

Es una pregunta de estilo si prefieres typedef . Sin él, si desea referirse al tipo de enumeración, necesita usar la enum strategy . Con eso, solo puedes decir strategy .

Ambas formas tienen sus pro y sus contras. El uno es más prolijo, pero mantiene los identificadores de tipo en el espacio de nombres de etiqueta donde no entrarán en conflicto con los identificadores ordinarios (piense en struct stat y en la función stat : estos tampoco entran en conflicto), y donde inmediatamente ve que es un tipo. El otro es más corto, pero trae identificadores de tipo al espacio de nombres ordinario.