Sind die Standard-Enum-Werte in C für alle Compiler gleich?


107

Wenn eine ENUM erklärt , wie unten dargestellt, legen alle C - Compiler die Standardwerte wie x=0, y=1und z=2auf beiden Linux und Windows - Systeme?

typedef enum {
    x,
    y,
    z
} someName;

3
Ja, es wird von den Standards verlangt, und ich bin sicher, dass jemand sie zitieren kann.
Nemo

Antworten:


115

Ja. Sofern Sie in der Definition der Aufzählung nichts anderes angeben, hat der anfängliche Aufzähler immer den Wert Null und der Wert jedes nachfolgenden Aufzählers ist eins größer als der vorherige Aufzähler.


14
Dieses identische Verhalten wird sowohl von C als auch von C ++ benötigt. In C ++ heißt es [dcl.enum]: "Wenn der erste Enumerator keinen Initialisierer hat, ist der Wert der entsprechenden Konstante Null. Eine Enumeratordefinition ohne Initialisierer gibt dem Enumerator den Wert, der durch Erhöhen des Werts des vorherigen Enumerators um eins erhalten wird."
Ben Voigt

3
Ja, und auch andere Sprachen, die mit dem Buchstaben C beginnen, wie C #.
James McNellis

70

C99 Standard

Der Entwurf des N1265 C99 lautet am 6.7.2.2/3 "Aufzählungsspezifizierer".

Ein Enumerator mit = definiert seine Aufzählungskonstante als den Wert des Konstantenausdrucks. Wenn der erste Enumerator no hat =, ist der Wert seiner Aufzählungskonstante 0. Jeder nachfolgende Enumerator mit no = definiert seine Aufzählungskonstante als den Wert des Konstantenausdrucks, der durch Addition von 1 zum Wert der vorherigen Aufzählungskonstante erhalten wird. (Die Verwendung von Enumeratoren mit = kann Aufzählungskonstanten mit Werten erzeugen, die andere Werte in derselben Aufzählung duplizieren.)

Folgendes gilt also immer für konforme Implementierungen:

Haupt c

#include <assert.h>
#include <limits.h>

enum E {
    E0,
    E1,
    E2 = 3,
    E3 = 3,
    E4,
    E5 = INT_MAX,
#if 0
    /* error: overflow in enumeration values */
    E6,
#endif
};

int main(void) {
    /* If unspecified, the first is 0. */
    assert(E0 == 0);
    assert(E1 == 1);
    /* Repeated number, no problem. */
    assert(E2 == 3);
    assert(E3 == 3);
    /* Continue from the last one. */
    assert(E4 == 4);
    assert(E5 == INT_MAX);
    return 0;
}

Kompilieren und ausführen:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

Getestet in Ubuntu 16.04, GCC 6.4.0.


7

Wenn der erste Wert der Aufzählungsvariablen nicht initialisiert wird, weist der C-Compiler automatisch den Wert 0 zu. Der Compiler erhöht den Wert der vorhergehenden Aufzählungsvariablen weiterhin um 1.

Z.B:

enum months{jan,feb,mar}

Erklärung: Der Wert von jan ist 0, feb ist 1, mar ist 2.

enum months{jan=123,feb=999,mar}

Erklärung: Der Wert von jan wird 123 sein, feb wird 999 sein, mar wird 1000 sein.

enum months{jan='a',feb='s',mar}

Erklärung: Der Wert von jan ist 'a', feb ist 's', mar ist 't'.


1
mar 't'ist nicht garantiert, es kann Zeichensätze geben, in denen die Buchstaben nicht in aufeinanderfolgender alphabetischer Reihenfolge sind
MM

-15

Ja, der Aufzählungswert bydefult beginnt bei jeder Plattform von 0 bis zum n-ten Element.


14
Überlegen Sie, wie Ihre Antwort zum Antwortpool beiträgt. Das heißt, wie fügt Ihre neue Antwort (5 Jahre später) etwas Neues hinzu, das in keiner anderen Antwort behandelt wird? Auf den ersten Blick scheint es weniger informativ zu sein als die beiden anderen Antworten.
LawfulEvil

2
Ehhh @LawfulEvil entspannen. Mehrere Antworten geben Menschen, die dies in Zukunft betrachten, mehrere Perspektiven. Das heißt, dies ist eine schlecht formatierte, nicht informative Antwort, aber reichlich Antworten an und für sich sind nicht schlecht.
Kenny Worden
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.