Namensräume
Varianten
Aktionen

Aufzählungen

Von cppreference.com
< c‎ | Sprache

Ein aufzählbarer Typ ist ein eigenständiger Typ, dessen Wert ein Wert seines zugrundeliegenden Typs ist (siehe unten), der die Werte explizit benannter Konstanten (Aufzählungskonstanten) enthält.

Inhalt

[bearbeiten] Syntax

Ein aufzählbarer Typ wird mithilfe des folgenden Aufzählungsspezifizierers als Typspezifizierer 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 Aufzählung ohne festen zugrundeliegenden Typ.
2) Deklariert eine Aufzählung mit dem festen zugrundeliegenden Typ type.

wobei enumerator-list eine durch Kommas getrennte Liste ist(mit erlaubtem abschließendem Komma)(seit C99) von enumerator, von denen jeder die Form hat

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

wobei

identifier, enumeration-constant - Bezeichner, die durch diese Deklaration eingeführt werden.
konstanter Ausdruck - Ganzzahliger Konstantausdruck dessen Wert als Wert vom Typ int darstellbar ist(bis C23). Wenn die Aufzählung einen festen zugrundeliegenden Typ hat, ist er als Wert vom Typ type darstellbar(seit C23)
attr-spec-seq - (C23) Optionale Liste von Attributen,
  • angewendet auf die gesamte Aufzählung, wenn sie nach enum erscheint,
  • angewendet auf den Enumerator, wenn er nach enumeration-constant erscheint.

Ähnlich wie bei struct oder union kann eine Deklaration, die einen aufzählbaren Typ und einen oder mehrere Aufzählungskonstanten einführt, auch ein oder mehrere Objekte dieses Typs oder davon abgeleitete Typen deklarieren.

enum color { RED, GREEN, BLUE } c = RED, *cp = &c;
// introduces the type enum color
// the integer constants RED, GREEN, BLUE
// the object c of type enum color
// the object cp of type pointer to enum color

[bearbeiten] Erklärung

Jede enumeration-constant, die im Körper eines Aufzählungsspezifizierers erscheint, wird zu einer Ganzzahlkonstante mit dem Typ int(bis C23) im umschließenden Gültigkeitsbereich und kann überall dort verwendet werden, wo Ganzzahlkonstanten benötigt werden (z. B. als case-Label oder als nicht-VLA-Arraygröße).

Während der Verarbeitung jeder Aufzählungskonstante in der Aufzählerliste ist der Typ der Aufzählungskonstante:

  • der zuvor deklarierte Typ, wenn es sich um eine Neudeklaration derselben Aufzählungskonstante handelt; oder,
  • der aufzählbare Typ, für eine Aufzählung mit festem zugrundeliegendem Typ; oder,
  • int, wenn es keine vorherigen Aufzählungskonstanten in der Aufzählerliste gibt und kein explizites = mit einem definierenden Ganzzahlkonstantausdruck vorhanden ist; oder,
  • int, wenn er explizit mit = angegeben wird und der Wert des Ganzzahlkonstantausdrucks als int darstellbar ist; oder,
  • der Typ des Ganzzahlkonstantausdrucks, wenn er explizit mit = angegeben wird und der Wert des Ganzzahlkonstantausdrucks nicht als int darstellbar ist; oder,
  • der Typ des Werts der letzten Aufzählungskonstante plus eins. Wenn ein solcher Ganzzahlkonstantausdruck beim Hinzufügen von 1 zum Wert der vorherigen Aufzählungskonstante überläuft oder wraparound-Effekte aufweist, nimmt der Typ entweder
    • einen passend großen vorzeichenbehafteten Ganzzahltyp (ausschließlich der bit-präzisen vorzeichenbehafteten Ganzzahltypen) an, der in der Lage ist, den Wert der vorherigen Aufzählungskonstante plus 1 darzustellen; oder,
    • einen passend großen vorzeichenlosen Ganzzahltyp (ausschließlich der bit-präzisen vorzeichenlosen Ganzzahltypen) an, der in der Lage ist, den Wert der vorherigen Aufzählungskonstante plus 1 darzustellen.

Ein vorzeichenbehafteter Ganzzahltyp wird gewählt, wenn die vorherige Aufzählungskonstante, zu der addiert wird, von vorzeichenbehaftetem Ganzzahltyp ist. Ein vorzeichenloser Ganzzahltyp wird gewählt, wenn die vorherige Aufzählungskonstante von vorzeichenlosem Ganzzahltyp ist. Wenn kein passend großer Ganzzahltyp, wie zuvor beschrieben, vorhanden ist, der den neuen Wert darstellen kann, dann hat die Aufzählung keinen Typ, der in der Lage ist, alle ihre Werte darzustellen.

(seit C23)
enum color { RED, GREEN, BLUE } r = RED;
switch(r)
{
case RED:
    puts("red");
    break;
case GREEN:
    puts("green");
    break;
case BLUE:
    puts("blue");
    break;
}

Wenn enumeration-constant von = constant-expression gefolgt wird, ist sein Wert der Wert dieses Konstantausdrucks. Wenn enumeration-constant nicht von = constant-expression gefolgt wird, ist sein Wert eins größer als der Wert des vorherigen Aufzählers in derselben Aufzählung. Der Wert des ersten Aufzählers (wenn er kein = 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 identifier selbst wird, wenn er verwendet wird, zum Namen des aufzählbaren Typs im Namensraum der Tag-Bezeichner und erfordert die Verwendung des Schlüsselworts enum (es sei denn, er wird in den normalen Namensraum typedef'd).

enum color { RED, GREEN, BLUE };
enum color r = RED; // OK
// color x = GREEN; // Error: color is not in ordinary name space
typedef enum color color_t;
color_t x = GREEN; // OK

Jeder aufzählbare Typ ohne festen zugrundeliegenden Typ(seit C23) ist kompatibel mit einem von: char, einem vorzeichenbehafteten Ganzzahltyp oder einem vorzeichenlosen Ganzzahltyp (ausschließlich bool und der bit-präzisen Ganzzahltypen)(seit C23). Es liegt in der Verantwortung der Implementierung, welcher Typ mit einem gegebenen aufzählbaren Typ kompatibel ist, aber welcher es auch sei, er muss in der Lage sein, alle Aufzählerwerte dieser Aufzählung darzustellen. Für alle Aufzählungen mit einem festen zugrundeliegenden Typ ist der aufzählbare Typ mit dem zugrundeliegenden Typ der Aufzählung kompatibel.(seit C23)

Der Aufzählungsmitgliedstyp für einen aufzählbaren Typ ohne festen zugrundeliegenden Typ nach Fertigstellung ist:

  • int, wenn alle Werte der Aufzählung als int darstellbar sind; oder,
  • der aufzählbare Typ.
(seit C23)
Alle Aufzählungen haben einen zugrundeliegenden Typ. Der zugrundeliegende Typ kann mit einem Enum-Typ-Spezifizierer explizit angegeben werden und ist dann sein 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 oder char ist. (seit C23)

Aufzählbare Typen sind Ganzzahltypen und können daher überall dort verwendet werden, wo andere Ganzzahltypen verwendet werden können, einschließlich impliziter Konvertierungen und arithmetischer Operatoren.

enum { ONE = 1, TWO } e;
long n = ONE; // promotion
double d = ONE; // conversion
e = 1.2; // conversion, e is now ONE
e = e + 1; // e is now TWO

[bearbeiten] Hinweise

Im Gegensatz zu struct oder union gibt es in C keine Vorwärtsdeklarationen von Enums.

enum Color; // Error: no forward-declarations for 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, gehorchen Bereichsregeln und nehmen am Typsystem teil.

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

or

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

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

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

Darüber hinaus, da eine struct oder union ihren Geltungsbereich in C nicht etabliert, können ein Aufzählbarer Typ und seine Aufzählungskonstanten in der Mitgliederspezifikation der ersteren eingeführt werden, und ihr Geltungsbereich ist derselbe wie der ersterer.

struct Element
{
    int z;
    enum State { SOLID, LIQUID, GAS, PLASMA } state;
} oxygen = { 8, GAS };
 
// type enum State and its enumeration constants stay visible here, e.g.
void foo(void)
{
    enum State e = LIQUID; // OK
    printf("%d %d %d ", e, oxygen.state, PLASMA); // prints 1 2 3
}

[bearbeiten] 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

[bearbeiten] 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 Typen (S. 41)
  • 6.7.2.2 Aufzählungsspezifizierer (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

[bearbeiten] Schlüsselwörter

enum

[bearbeiten] Siehe auch

C++-Dokumentation für Aufzählungsklarstellung