Wie definiere ich einen Aufzählungstyp (Enum) in C?

Lesezeit: 8 Minuten

Benutzeravatar von lindelof
Lindelof

Ich bin mir nicht sicher, was die richtige Syntax für die Verwendung von C-Enumerationen ist. Ich habe folgenden Code:

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

Dies wird jedoch nicht kompiliert, mit folgendem Fehler:

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

Was mache ich falsch?

  • Jahre alte Frage, wahrscheinlich wird das niemand sehen; aber warum gibt das einen fehler aus? Es sollte nach meinem Wissen einwandfrei funktionieren, da es in der Frage steht.

    – Utkan Geser

    15. März 2014 um 16:37 Uhr

  • @Solver warum ist diese Syntax falsch?

    – MKG

    22. Oktober 2015 um 15:51 Uhr


  • @MCQ, necroing the necro’d necro: Die in der Frage dargestellte Syntax lautet nicht falsch in C. Es erklärt strategy als einen anonymen Aufzählungstyp und weist ihm einen der deklarierten Werte dieses Typs zu. Außerdem, wenn ich den präsentierten Code in einen ansonsten trivialen umschließe main() funktioniert, dann kompiliert es für mich ohne Warnung mit gcc 4.4.7. Einige der Antworten implizieren dasselbe, wenn auch nicht in so vielen Worten.

    – Johannes Bollinger

    9. Februar 2016 um 14:50 Uhr

  • Bei den meisten Antworten fehlt die Tatsache, dass die beiden Codezeilen in der Frage nicht nur ein Ausschnitt sind. Sie sind die gesamte Quelldatei. Wenn diese beiden Zeilen im Hauptteil einer Funktion enthalten sind, liegt kein Fehler vor. Wenn sie außerhalb einer Funktionsdeklaration im Dateibereich erscheinen, erhalten Sie die Fehler, nach denen das OP gefragt hat (und einige andere, als ich es versucht habe). Das grundlegende Problem ist, dass der Compiler versucht, es zu behandeln strategy = IMMEDIATE; als Erklärung. Es hat eine Form, die in Pre-ANSI C legal gewesen wäre, aber in modernem C ist es illegal. Zuweisungen sind im Dateibereich nicht zulässig.

    – Keith Thompson

    21. September 2017 um 22:08 Uhr

  • @Löser: enum strategy { ... }; definiert einen Aufzählungstyp namens enum strategywo strategy ist das Etikett. enum { ... } strategy; definiert einen anonymen Aufzählungstyp (kein Tag) und ein einzelnes Objekt dieses Typs mit dem Namen strategy. Beide sind vollkommen legal; sie bedeuten nur verschiedene Dinge.

    – Keith Thompson

    21. September 2017 um 22:29 Uhr

Es ist erwähnenswert, dass Sie dies nicht tun brauchen a typedef. Sie können es einfach wie folgt tun

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

Es ist eine Stilfrage, ob Sie es bevorzugen typedef. Ohne sie müssen Sie verwenden, wenn Sie auf den Aufzählungstyp verweisen möchten enum strategy. Damit kann man nur sagen strategy.

Beide Wege haben ihre Vor- und Nachteile. Der eine ist wortreicher, behält aber Typbezeichner im Tag-Namespace, wo sie nicht mit gewöhnlichen Bezeichnern in Konflikt geraten (denken Sie an struct stat und die stat Funktion: Diese stehen auch nicht in Konflikt) und wo Sie sofort sehen, dass es sich um einen Typ handelt. Der andere ist kürzer, bringt aber Typbezeichner in den gewöhnlichen Namensraum.

  • Es sollte nicht die akzeptierte Antwort sein, weil es falsch ist. Sie können die Aufzählungsstrategie { … } nicht verwenden; in C – Sie können und sollten es jedoch in C++ tun.

    – Klarer

    6. Mai 2014 um 7:31 Uhr


  • @Clearer: Dieser Code funktioniert perfekt. Hier ist ein funktionierendes Beispiel: ideone.com/T0YV17 Beachten Sie, dass es die verwendet enum Schlüsselwort in beiden Zeilen.

    – Richie Hindle

    6. Mai 2014 um 7:47 Uhr


  • Oder “typedef enum Strategy { RANDOM, IMMEDIATE, SEARCH } Strategy_t;” und der Entwickler, der die Aufzählung verwendet, kann jede beliebige Konvention verwenden.

    – Andy Nugent

    13. November 2014 um 12:05 Uhr

  • das funktioniert hervorragend: enum strategy { RANDOM, IMMEDIATE, SEARCH }; dann, wenn Sie eine Instanz dieser Aufzählung wollen: `enum-Strategie myEnum;

    – Benutzer3629249

    24. Januar 2016 um 4:37 Uhr

  • @AndyNugent tu das nicht! *_t-Typen sind von POSIX reserviert

    – osven

    16. August 2017 um 21:14 Uhr

Benutzeravatar von RichieHindle
Richie Hindle

Das Deklarieren einer Enum-Variablen erfolgt wie folgt:

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

Sie können jedoch eine verwenden typedef um die Variablendeklarationen zu verkürzen, etwa so:

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

Es ist eine gute Idee, eine Namenskonvention zu haben, um zwischen Typen und Variablen zu unterscheiden:

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

  • Aber OP wollte eine Variable eines anonymen Aufzählungstyps

    – osven

    16. August 2017 um 21:12 Uhr

  • Könnte ich nicht einfach tippen enum MyEnum {} myVar; und dann die Variable verwenden myVar folgendermaßen: myVar = SOMEENUMCONSTANT;

    – Matschig

    21. September 2017 um 21:38 Uhr

Benutzeravatar von Tarc
Tarc

Sie versuchen zu erklären strategy zweimal, und deshalb erhalten Sie den obigen Fehler. Folgendes funktioniert ohne Beanstandungen (kompiliert mit gcc -ansi -pedantic -Wall):

#include <stdio.h>

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

int main(int argc, char** argv){
    printf("strategy: %d\n", strategy);

    return 0;
}

Wenn anstelle des obigen die zweite Zeile geändert wurde in:

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

Anhand der Warnungen konnten Sie Ihren Fehler leicht erkennen:

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

Also nahm der Compiler strategy = IMMEDIATE für eine Deklaration einer Variablen genannt strategy mit Standardtyp intaber es gab bereits eine vorherige Deklaration einer Variablen mit diesem Namen.

Wenn Sie die Aufgabe jedoch in der main() Funktion, es wäre ein gültiger Code:

#include <stdio.h>

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

int main(int argc, char** argv){
    strategy=SEARCH;
    printf("strategy: %d\n", strategy);

    return 0;
}

Wenn du sagst

enum {RANDOM, IMMEDIATE, SEARCH} strategy;

Sie erstellen eine einzelne Instanzvariable namens “Strategie” einer namenlosen Aufzählung. Dies ist nicht sehr nützlich – Sie benötigen eine Typedef:

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

Wie geschrieben, an Ihrem Code ist nichts falsch. Sind Sie sicher, dass Sie so etwas noch nicht getan haben?

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

Auf welche Zeilen zeigen die Fehlermeldungen? Wenn es heißt “vorherige Erklärung der ‘Strategie’ war hier”, was ist “hier” und was zeigt es?

  • Das hat er wahrscheinlich strategy = IMMEDIATE; im Dateibereich. Außerhalb aller Funktionen kann eine Zuweisung im Dateibereich nicht erfolgen. Also versuchte der Compiler, das Beste aus dem Fehler zu machen und nahm an, dass er es meinte int strategy = IMMEDIATE;an welcher Stelle der Konflikt stattfand.

    – Johannes Schaub – litb

    9. Juli 2009 um 16:06 Uhr

  • Dies ist die beste Antwort, die anderen Antworten sind so verwirrend, dass es schmerzhaft ist.

    – abschalten

    29. April 2015 um 8:56 Uhr

Das ist erwähnenswert in C++ Sie können “enum” verwenden, um einen neuen Typ zu definieren, ohne eine typedef-Anweisung zu benötigen.

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

Ich finde diese Herangehensweise viel freundlicher.

[edit – clarified C++ status – I had this in originally, then removed it!]

  • Das hat er wahrscheinlich strategy = IMMEDIATE; im Dateibereich. Außerhalb aller Funktionen kann eine Zuweisung im Dateibereich nicht erfolgen. Also versuchte der Compiler, das Beste aus dem Fehler zu machen und nahm an, dass er es meinte int strategy = IMMEDIATE;an welcher Stelle der Konflikt stattfand.

    – Johannes Schaub – litb

    9. Juli 2009 um 16:06 Uhr

  • Dies ist die beste Antwort, die anderen Antworten sind so verwirrend, dass es schmerzhaft ist.

    – abschalten

    29. April 2015 um 8:56 Uhr

@ThoAppelsin in seinem Kommentar zur Frage hat Recht. Das in der Frage gepostete Code-Snippet ist gültig und fehlerfrei. Der Fehler, den Sie haben, muss auf eine andere schlechte Syntax an einer anderen Stelle Ihrer C-Quelldatei zurückzuführen sein. enum{a,b,c}; definiert drei symbolische Konstanten (a, b und c), die ganze Zahlen mit Werten sind 0,1 und 2 bzw., aber wenn wir verwenden enum Das liegt daran, dass wir uns normalerweise nicht um den spezifischen ganzzahligen Wert kümmern, sondern uns mehr um die Bedeutung des symbolischen Konstantennamens kümmern. Dies bedeutet, dass Sie Folgendes haben können:

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

und dies wird ausgegeben 1.

Auch hier gilt:

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

und wird das gleiche wie zuvor ausgeben.

Wenn du das tust:

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

Sie werden einen Fehler haben, aber wenn Sie dies tun:

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

Sie werden keinen Fehler haben.

du kannst das:

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

und aa wird eine Integer-Variable mit Wert sein 0. aber das kannst du auch machen:

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

und wird den gleichen Effekt haben (d.h. aa ein sein int mit 0 Wert).

Sie können dies auch tun:

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

und aa wird sein int mit Wert 7.

weil Sie die symbolische Konstantendefinition nicht mit der Verwendung von wiederholen können enumwie ich bereits sagte, müssen Sie Tags verwenden, wenn Sie deklarieren möchten int vars mit der Verwendung von enum:

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

die Verwendung von typedef es soll Sie davor bewahren, jedes Mal zu schreiben enum tag1 Variable zu definieren. Mit typedef du kannst einfach tippen Tag1:

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

Sie können auch haben:

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

Als letztes sei gesagt, dass es besser ist, Großbuchstaben zu verwenden, da wir über definierte symbolische Konstanten sprechen enumdas heißt zum Beispiel:

enum {A,B,C};

Anstatt von

enum {a,b,c};

1426680cookie-checkWie definiere ich einen Aufzählungstyp (Enum) in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy