Namespaces
Variants

Enumerations

From cppreference.net

Ein enumerated type ist ein eigenständiger Typ , dessen Wert ein Wert seines underlying type ist (siehe unten), der die Werte explizit benannter Konstanten ( enumeration constants ) umfasst.

Inhaltsverzeichnis

Syntax

Aufzählungstyp wird mit dem folgenden Aufzählungsspezifizierer als Typ-Spezifizierer in der Deklarationsgrammatik deklariert:

enum attr-spec-seq  (optional) identifier  (optional) { enumerator-list } (1)
enum attr-spec-seq  (optional) identifier  (optional) : type { enumerator-list } (2) (seit C23)
1) Deklariert eine Enumeration ohne festgelegten zugrundeliegenden Typ.
2) Deklariert eine Enumeration mit festgelegtem zugrundeliegendem Typ type .

wobei enumerator-list eine durch Kommas getrennte Liste (mit nachfolgendem Komma erlaubt) (seit C99) von enumerator ist, von denen jeder die folgende Form hat:

enumeration-constant attr-spec-seq  (optional) (1)
enumeration-constant attr-spec-seq  (optional) = constant-expression (2)

wo

identifier , enumeration-constant - Bezeichner, die durch diese Deklaration eingeführt werden
constant-expression - Integer-Konstantenausdruck dessen Wert als Wert vom Typ int darstellbar ist (bis C23) . Wenn die Enumeration einen festen zugrundeliegenden Typ hat, darstellbar als Wert vom type (seit C23)
attr-spec-seq - (C23) optionale Liste von Attributen ,
  • angewendet auf die gesamte Enumeration, wenn nach enum erscheint,
  • angewendet auf den enumerator , wenn nach enumeration-constant erscheint

Wie bei struct oder union kann eine Deklaration, die einen Aufzählungstyp und eine oder mehrere Aufzählungskonstanten einführt, auch ein oder mehrere Objekte dieses Typs oder davon abgeleiteter Typen deklarieren.

enum color { RED, GREEN, BLUE } c = RED, *cp = &c;
// führt den Typ enum color ein
// die Integer-Konstanten RED, GREEN, BLUE
// das Objekt c vom Typ enum color
// das Objekt cp vom Typ Zeiger auf enum color

Erklärung

Jede enumeration-constant , die im Rumpf einer Aufzählungsspezifikation erscheint, wird zu einer ganzzahligen Konstante mit dem Typ int (bis C23) im umschließenden Gültigkeitsbereich und kann überall verwendet werden, wo ganzzahlige Konstanten erforderlich sind (z.B. als case-Label oder als Nicht-VLA-Arraygröße).

Während der Verarbeitung jeder Aufzählungskonstante in der Enumeratorliste muss der Typ der Aufzählungskonstante sein:

  • der zuvor deklarierte Typ, falls es sich um eine Neudeklaration derselben Aufzählungskonstante handelt; oder,
  • der aufgezählte Typ, für eine Aufzählung mit festem zugrundeliegenden Typ; oder,
  • int , falls es keine vorherigen Aufzählungskonstanten in der Enumeratorliste gibt und kein explizites = mit einem definierenden ganzzahligen konstanten Ausdruck; oder,
  • int , falls explizit mit = angegeben und der Wert des ganzzahligen konstanten Ausdrucks durch einen int darstellbar ist; oder,
  • der Typ des ganzzahligen konstanten Ausdrucks, falls explizit mit = angegeben und falls der Wert des ganzzahligen konstanten Ausdrucks nicht durch int darstellbar ist; oder,
  • der Typ des Werts der letzten Aufzählungskonstante plus 1. Falls ein solcher ganzzahliger konstanter Ausdruck durch Addition von 1 überlaufen oder umschlagen würde, nimmt der Typ entweder:
    • einen geeignet großen vorzeichenbehafteten Ganzzahltyp (ausschließlich der bitgenauen vorzeichenbehafteten Ganzzahltypen) an, der den Wert der vorherigen Aufzählungskonstante plus 1 darstellen kann; oder,
    • einen geeignet großen vorzeichenlosen Ganzzahltyp (ausschließlich der bitgenauen vorzeichenlosen Ganzzahltypen) an, der den Wert der vorherigen Aufzählungskonstante plus 1 darstellen kann.

Ein vorzeichenbehafteter Ganzzahltyp wird gewählt, falls die zu addierende vorherige Aufzählungskonstante vom vorzeichenbehafteten Ganzzahltyp ist. Ein vorzeichenloser Ganzzahltyp wird gewählt, falls die vorherige Aufzählungskonstante vom vorzeichenlosen Ganzzahltyp ist. Falls es keinen geeignet großen zuvor beschriebenen Ganzzahltyp gibt, der den neuen Wert darstellen kann, dann hat die Aufzählung keinen Typ, der alle ihre Werte darstellen kann.

(seit C23)
enum color { RED, GREEN, BLUE } r = RED;
switch(r)
{
case RED:
    puts("rot");
    break;
case GREEN:
    puts("grün");
    break;
case BLUE:
    puts("blau");
    break;
}

Wenn enumeration-constant von = constant-expression gefolgt wird, ist ihr Wert der Wert dieses konstanten Ausdrucks. Wenn enumeration-constant nicht von = constant-expression gefolgt wird, ist ihr Wert um eins größer als der Wert des vorherigen Enumerators in derselben Enumeration. Der Wert des ersten Enumerators (falls er nicht = constant-expression verwendet) ist null.

enum Foo { A, B, C = 10, D, E = 1, F, G = F + C };
// A=0, B=1, C=10, D=11, E=1, F=2, G=12

Der Bezeichner selbst, falls verwendet, wird zum Namen des Aufzählungstyps im Namensraum der Tags und erfordert die Verwendung des Schlüsselworts enum (sofern nicht mittels typedef in den gewöhnlichen Namensraum verschoben).

enum color { RED, GREEN, BLUE };
enum color r = RED; // OK
// color x = GREEN; // Fehler: color ist nicht im gewöhnlichen Namensraum
typedef enum color color_t;
color_t x = GREEN; // OK

Jeder Aufzählungstyp ohne festgelegten zugrundeliegenden Typ (seit C23) ist kompatibel mit einem der folgenden Typen: char , einem vorzeichenbehafteten Ganzzahltyp oder einem vorzeichenlosen Ganzzahltyp (ausgenommen bool und die bitgenauen Ganzzahltypen) (seit C23) . Es ist implementierungsdefiniert, welcher Typ mit einem bestimmten Aufzählungstyp kompatibel ist, aber unabhängig davon muss er in der Lage sein, alle Enumeratorwerte dieser Aufzählung darzustellen. Für alle Aufzählungen mit einem festgelegten zugrundeliegenden Typ ist der Aufzählungstyp mit dem zugrundeliegenden Typ der Aufzählung kompatibel. (seit C23)

Der Aufzählungsmitgliedtyp für einen Aufzählungstyp ohne festgelegten zugrundeliegenden Typ nach Abschluss ist:

  • int wenn alle Werte der Aufzählung als int darstellbar sind; oder,
  • der Aufzählungstyp selbst.
(seit C23)
Alle Aufzählungen haben einen zugrundeliegenden Typ. Der zugrundeliegende Typ kann explizit mit einem enum-type-specifier angegeben werden und ist dann dessen fester zugrundeliegender Typ. Wenn er nicht explizit angegeben wird, ist der zugrundeliegende Typ der kompatible Typ der Aufzählung, der entweder ein vorzeichenbehafteter oder vorzeichenloser Ganzzahltyp ist, oder char . (seit C23)

Aufzählungstypen sind ganzzahlige Typen und können daher überall dort verwendet werden, wo andere ganzzahlige Typen verwendet werden können, einschließlich bei impliziten Konvertierungen und arithmetischen Operatoren .

enum { ONE = 1, TWO } e;
long n = ONE; // Höherstufung
double d = ONE; // Konvertierung
e = 1.2; // Konvertierung, e ist jetzt ONE
e = e + 1; // e ist jetzt TWO

Hinweise

Im Gegensatz zu struct oder union gibt es in C keine vorwärtsdeklarierten Enums:

enum Color; // Fehler: keine Vorwärtsdeklarationen für Enums in C
enum Color { RED, GREEN, BLUE };

Aufzählungen ermöglichen die Deklaration benannter Konstanten auf eine bequemere und strukturiertere Weise als #define ; sie sind im Debugger sichtbar, befolgen Bereichsregeln und nehmen am Typsystem teil.

#define TEN 10
struct S { int x : TEN; }; // OK

oder

enum { TEN = 10 };
struct S { int x : TEN; }; // ebenfalls OK

Seit C23 kann constexpr für denselben Zweck verwendet werden:

constexpr int TEN = 10;
struct S { int x : TEN; }; // ebenfalls OK

Darüber hinaus, da ein struct oder eine union in C keinen eigenen Gültigkeitsbereich etabliert, können ein Aufzählungstyp und seine Aufzählungskonstanten in der Memberspezifikation des ersteren eingeführt werden, und ihr Gültigkeitsbereich ist derselbe wie der des ersteren, danach.

struct Element
{
    int z;
    enum State { SOLID, LIQUID, GAS, PLASMA } state;
} oxygen = { 8, GAS };
// Der Typ enum State und seine Aufzählungskonstanten bleiben hier sichtbar, z.B.
void foo(void)
{
    enum State e = LIQUID; // OK
    printf("%d %d %d ", e, oxygen.state, PLASMA); // gibt 1 2 3 aus
}

Beispiel

#include <stdio.h>
int main(void)
{
    enum TV { FOX = 11, CNN = 25, ESPN = 15, HBO = 22, MAX = 30, NBC = 32 };
    printf("List of cable stations:\n");
    printf(" FOX: \t%2d\n", FOX);
    printf(" HBO: \t%2d\n", HBO);
    printf(" MAX: \t%2d\n", MAX);
}

Ausgabe:

List of cable stations:
 FOX:   11
 HBO:   22
 MAX:   30

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 6.2.5/21 Typen (S: 39)
  • 6.7.2.2 Aufzählungsspezifizierer (S: 107-112)
  • C17-Standard (ISO/IEC 9899:2018):
  • 6.2.5/16 Typen (S: 32)
  • 6.7.2.2 Aufzählungsspezifizierer (S: 84-85)
  • C11-Standard (ISO/IEC 9899:2011):
  • 6.2.5/16 Types (S. 41)
  • 6.7.2.2 Enumeration specifiers (S. 117-118)
  • C99-Standard (ISO/IEC 9899:1999):
  • 6.2.5/16 Typen (S: 35)
  • 6.7.2.2 Aufzählungsspezifizierer (S: 105-106)
  • C89/C90 Standard (ISO/IEC 9899:1990):
  • 3.1.2.5 Typen
  • 3.5.2.2 Aufzählungsspezifizierer

Schlüsselwörter

enum

Siehe auch

C++ Dokumentation für Enumeration-Deklaration