Je ne sais pas quelle est la syntaxe appropriée pour utiliser les énumérations. J'ai le code suivant:
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
Mais cela ne compile pas, avec l'erreur suivante:
error: conflicting types for ‘strategy’
error: previous declaration of ‘strategy’ was here
Qu'est-ce que je fais mal?
Déclarer une variable enum se fait comme ceci:
enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy my_strategy = IMMEDIATE;
Cependant, vous pouvez utiliser une variable typedef
pour raccourcir les déclarations de variable, comme ceci:
typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy my_strategy = IMMEDIATE;
Avoir une convention de nommage pour distinguer les types et les variables est une bonne idée:
typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
strategy_type my_strategy = IMMEDIATE;
Cela vaut la peine de souligner que vous n'avez pas besoin a typedef
. Vous pouvez simplement le faire comme suit
enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;
C'est une question de style si vous préférez typedef
. Sans lui, si vous souhaitez faire référence au type d'énumération, vous devez utiliser enum strategy
. Avec cela, vous pouvez simplement dire strategy
.
Les deux manières ont leurs avantages et inconvénients. L'un est plus verbeux, mais conserve les identifiants de type dans l'espace de noms de balises où ils ne seront pas en conflit avec les identifiants ordinaires (pensez à struct stat
et à la fonction stat
: ils ne sont pas en conflit non plus) et où vous voyez immédiatement qu'il s'agit d'un type . L'autre est plus court, mais introduit les identificateurs de type dans l'espace de noms ordinaire.
Vous essayez de déclarer strategy
deux fois, et c’est pourquoi vous obtenez l’erreur ci-dessus. Ce qui suit fonctionne sans aucune plainte (compilé avec 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 au lieu de ce qui précède, la deuxième ligne a été modifiée en:
...
enum { RANDOM, IMMEDIATE, SEARCH } strategy;
strategy = IMMEDIATE;
...
Parmi les avertissements, vous pouvez facilement voir votre erreur:
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
Le compilateur a donc pris strategy = IMMEDIATE
pour la déclaration d'une variable appelée strategy
avec le type par défaut int
, mais il existait déjà une déclaration précédente d'une variable portant ce nom.
Toutefois, si vous avez placé l'affectation dans la fonction main()
, il s'agirait d'un code valide:
#include <stdio.h>
enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;
int main(int argc, char** argv){
strategy=SEARCH;
printf("strategy: %d\n", strategy);
return 0;
}
Quand tu dis
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
vous créez une seule variable d'instance, appelée "stratégie" d'une énumération sans nom. Ce n'est pas une chose très utile à faire - vous avez besoin d'un typedef:
typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType;
StrategyType strategy = IMMEDIATE;
Comme écrit, il n'y a rien de mal avec votre code. Êtes-vous sûr de ne pas avoir fait quelque chose comme
int strategy;
...
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
Sur quelles lignes pointent les messages d'erreur? Quand on dit "la déclaration de stratégie précédente était ici", qu'est-ce que "ici" et que montre-t-il?
@ThoAppelsin dans son commentaire à la question postée est juste. L'extrait de code publié dans la question est valide et sans erreur. L'erreur que vous avez doit être due à une autre syntaxe incorrecte à n'importe quel endroit de votre fichier source c. enum{a,b,c};
définit trois constantes symboliques (a
, b
et c
) qui sont des entiers avec les valeurs 0
, 1
et 2
respectivement, mais lorsque nous utilisons enum
c'est parce que nous ne nous soucions pas de la valeur entière spécifique, nous nous soucions davantage du nom de la constante symbolique. Cela signifie que vous pouvez avoir ceci:
#include <stdio.h>
enum {a,b,c};
int main(){
printf("%d\n",b);
return 0;
}
et ceci produira 1
.
Ce sera également valide:
#include <stdio.h>
enum {a,b,c};
int bb=b;
int main(){
printf("%d\n",bb);
return 0;
}
et produira la même chose que précédemment.
Si tu fais ça:
enum {a,b,c};
enum {a,b,c};
vous aurez une erreur, mais si vous faites ceci:
enum alfa{a,b,c};
enum alfa;
vous n'aurez aucune erreur.
tu peux le faire:
enum {a,b,c};
int aa=a;
et aa
sera une variable entière avec la valeur 0
. mais vous pouvez aussi faire ceci:
enum {a,b,c} aa= a;
et aura le même effet (c’est-à-dire que aa
sera une int
avec une valeur 0
).
vous pouvez aussi faire ceci:
enum {a,b,c} aa= a;
aa= 7;
et aa
sera int
avec la valeur 7
.
comme vous ne pouvez pas répéter la définition de constante symbolique avec l'utilisation de enum
, comme je l'ai dit précédemment, vous devez utiliser des balises si vous souhaitez déclarer int
vars avec l'utilisation de enum
:
enum tag1 {a,b,c};
enum tag1 var1= a;
enum tag1 var2= b;
l'utilisation de typedef
permet d'éviter d'écrire chaque fois enum tag1
pour définir une variable. Avec typedef
, vous pouvez simplement taper Tag1
:
typedef enum {a,b,c} Tag1;
Tag1 var1= a;
Tag1 var2= b;
Vous pouvez aussi avoir:
typedef enum tag1{a,b,c}Tag1;
Tag1 var1= a;
enum tag1 var2= b;
La dernière chose à dire, c’est que puisque nous parlons de constantes symboliques définies, il est préférable d’utiliser des lettres majuscules lorsque vous utilisez enum
, c’est-à-dire:
enum {A,B,C};
au lieu de
enum {a,b,c};
Il convient de noter que en C++ vous pouvez utiliser "enum" pour définir un nouveau type sans avoir besoin d'une instruction typedef.
enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;
Je trouve cette approche beaucoup plus conviviale.
[modifier - statut C++ clarifié - je l'avais à l'origine, puis je l'ai supprimé!]
Il semble y avoir une confusion à propos de la déclaration.
Quand strategy
centre avant {RANDOM, IMMEDIATE, SEARCH}
comme ci-dessous,
enum strategy {RANDOM, IMMEDIATE, SEARCH};
vous créez un nouveau type nommé enum strategy
. Cependant, lors de la déclaration de la variable, vous devez utiliser enum strategy
lui-même. Vous ne pouvez pas simplement utiliser strategy
. Donc, ce qui suit est invalide.
enum strategy {RANDOM, IMMEDIATE, SEARCH};
strategy a;
Alors que, ce qui suit est valide
enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy queen = RANDOM;
enum strategy king = SEARCH;
enum strategy pawn[100];
Lorsque strategy
vient après {RANDOM, IMMEDIATE, SEARCH}
, vous créez une énumération anonyme, puis vous déclarez que strategy
est une variable de ce type.
Alors maintenant, vous pouvez faire quelque chose comme
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = RANDOM;
Cependant, vous ne pouvez déclarer aucune autre variable de type enum {RANDOM, IMMEDIATE, SEARCH}
car vous ne l'avez jamais nommée. Donc ce qui suit est invalide
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
enum strategy a = RANDOM;
Vous pouvez aussi combiner les deux définitions
enum strategy {RANDOM, IMMEDIATE, SEARCH} a, b;
a = RANDOM;
b = SEARCH;
enum strategy c = IMMEDIATE;
Typedef
, comme indiqué précédemment, est utilisé pour créer une déclaration de variable plus courte.
typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
Vous avez maintenant dit au compilateur que enum {RANDOM, IMMEDIATE, SEARCH}
est synonyme de strategy
. Alors maintenant, vous pouvez utiliser librement strategy
comme type de variable. Vous n'avez plus besoin de taper enum strategy
. Ce qui suit est valide maintenant
strategy x = RANDOM;
Vous pouvez également combiner Typedef avec le nom d’énum pour obtenir
typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;
L'utilisation de cette méthode présente peu d'avantages, mis à part le fait que vous pouvez maintenant utiliser strategy
et enum strategyName
de façon interchangeable.
typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;
enum strategyName a = RANDOM;
strategy b = SEARCH;
Si vous déclarez le nom pour l'énumération, aucune erreur ne se produira.
Si non déclaré, vous devez utiliser une typedef
:
enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
Il n'y aura pas d'erreur.
Ma construction préférée et uniquement utilisée a toujours été:
typedef enum MyBestEnum
{
/* good enough */
GOOD = 0,
/* even better */
BETTER,
/* divine */
BEST
};
Je crois que cela va résoudre votre problème que vous avez. Utiliser un nouveau type est de mon point de vue une bonne option.
La réponse de Tarc est la meilleure.
Une grande partie de la discussion enum est un hareng rouge.
Comparez cet extrait de code: -
int strategy;
strategy = 1;
void some_function(void)
{
}
qui donne
error C2501: 'strategy' : missing storage-class or type specifiers
error C2086: 'strategy' : redefinition
avec celui-ci qui compile sans problème.
int strategy;
void some_function(void)
{
strategy = 1;
}
La variable strategy
doit être définie lors de la déclaration ou à l'intérieur d'une fonction, etc. Vous ne pouvez pas écrire de logiciel arbitraire - des assignations en particulier - à la portée globale.
Le fait qu’il ait utilisé enum {RANDOM, IMMEDIATE, SEARCH} au lieu de int n’est pertinent que dans la mesure où il a confondu des personnes qui ne peuvent voir au-delà . l'auteur a mal agi.
Alors maintenant, vous devriez pouvoir voir pourquoi le premier de l'exemple ci-dessous est faux et les trois autres vont bien.
Exemple 1. FAUX!
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
void some_function(void)
{
}
Exemple 2. DROIT.
enum {RANDOM, IMMEDIATE, SEARCH} strategy = IMMEDIATE;
void some_function(void)
{
}
Exemple 3. DROIT.
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
void some_function(void)
{
strategy = IMMEDIATE;
}
Exemple 4. DROIT.
void some_function(void)
{
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
}
Si vous avez un programme opérationnel, vous devriez simplement pouvoir coller ces extraits dans votre programme et voir que certains compilent et d'autres non.
J'ai essayé avec gcc et, pour mon besoin, j'étais obligé d'utiliser la dernière alternative, de compiler sans erreur.
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);