C.
enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;
Deklaration, die als vorläufige Definition einer vorzeichenbehafteten Ganzzahl s
mit vollständigem Typ fungiert, und Deklaration, die als vorläufige Definition einer vorzeichenbehafteten Ganzzahl q
mit unvollständigem Typ im Bereich fungiert (die in den vollständigen Typ im Bereich aufgelöst wird, da die Typdefinition an einer beliebigen Stelle im Bereich vorhanden ist scope) (wie bei jeder vorläufigen Definition können die Bezeichner q
und s
mit der unvollständigen oder vollständigen Version desselben Typs int
oder enum stuff
mehrmals neu deklariert werden, jedoch nur einmal im Bereich definiert werden, dh int q = 3; und können nur in einem Unterbereich neu definiert werden, und nur nach der Definition verwendbar). Außerdem können Sie den vollständigen Typ nur enum stuff
einmal im Bereich verwenden, da er als Typdefinition fungiert.
Eine Definition des Compiler-Aufzählungstyps für enum stuff
wird auch im Dateibereich (vor und nach verwendbar) sowie eine Vorwärts-Typdeklaration vorhanden sein (der Typ enum stuff
kann mehrere Deklarationen enthalten, aber nur eine Definition / Vervollständigung im Bereich und kann in einem Unterbereich neu definiert werden). . Es fungiert auch als eine Compiler - Direktive zu ersetzen a
mit rvalue 0
, b
mit -4
, c
mit 5
, d
mit -2
, e
mit -3
, f
mit -1
und g
mit -2
in dem aktuellen Bereich. Die Aufzählungskonstanten gelten jetzt nach der Definition bis zur nächsten Neudefinition in einer anderen Aufzählung, die sich nicht auf derselben Bereichsebene befinden kann.
typedef enum bool {false, true} bool;
//this is the same as
enum bool {false, true};
typedef enum bool bool;
//or
enum bool {false, true};
typedef unsigned int bool;
//remember though, bool is an alias for _Bool if you include stdbool.h.
//and casting to a bool is the same as the !! operator
Der Tag - Namespace von ENUM, struct und union geteilt ist getrennt und muss vom Typ Schlüsselwort (Enum, struct oder union) vorangestellt werden , in C dh nach enum a {a} b
, enum a c
verwendet werden muss , und nicht a c
. Da der Tag-Namespace vom Bezeichner-Namespace getrennt ist, enum a {a} b
ist dies zulässig, jedoch enum a {a, b} b
nicht, da sich die Konstanten im selben Namespace wie die Variablen-Bezeichner befinden, dem Bezeichner-Namespace.typedef enum a {a,b} b
ist ebenfalls nicht zulässig, da typedef-names Teil des Bezeichner-Namespace sind.
Der Typ enum bool
und die Konstanten folgen dem folgenden Muster in C:
+--------------+-----+-----+-----+
| enum bool | a=1 |b='a'| c=3 |
+--------------+-----+-----+-----+
| unsigned int | int | int | int |
+--------------+-----+-----+-----+
+--------------+-----+-----+-----+
| enum bool | a=1 | b=-2| c=3 |
+--------------+-----+-----+-----+
| int | int | int | int |
+--------------+-----+-----+-----+
+--------------+-----+---------------+-----+
| enum bool | a=1 |b=(-)0x80000000| c=2 |
+--------------+-----+---------------+-----+
| unsigned int | int | unsigned int | int |
+--------------+-----+---------------+-----+
+--------------+-----+---------------+-----+
| enum bool | a=1 |b=(-)2147483648| c=2 |
+--------------+-----+---------------+-----+
| unsigned int | int | unsigned int | int |
+--------------+-----+---------------+-----+
+-----------+-----+---------------+------+
| enum bool | a=1 |b=(-)0x80000000| c=-2 |
+-----------+-----+---------------+------+
| long | int | long | int |
+-----------+-----+---------------+------+
+-----------+-----+---------------+------+
| enum bool | a=1 | b=2147483648 | c=-2 |
+-----------+-----+---------------+------+
| long | int | long | int |
+-----------+-----+---------------+------+
+-----------+-----+---------------+------+
| enum bool | a=1 | b=-2147483648 | c=-2 |
+-----------+-----+---------------+------+
| int | int | int | int |
+-----------+-----+---------------+------+
+---------------+-----+---------------+-----+
| enum bool | a=1 | b=99999999999 | c=1 |
+---------------+-----+---------------+-----+
| unsigned long | int | unsigned long | int |
+---------------+-----+---------------+-----+
+-----------+-----+---------------+------+
| enum bool | a=1 | b=99999999999 | c=-1 |
+-----------+-----+---------------+------+
| long | int | long | int |
+-----------+-----+---------------+------+
Dies kompiliert gut in C:
#include <stdio.h>
enum c j;
enum c{f, m} p;
typedef int d;
typedef int c;
enum c j;
enum m {n} ;
int main() {
enum c j;
enum d{l};
enum d q;
enum m y;
printf("%llu", j);
}
C ++
In C ++ können Aufzählungen einen Typ haben
enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error
In dieser Situation haben die Konstanten und der Bezeichner alle denselben Typ, bool, und es tritt ein Fehler auf, wenn eine Zahl nicht durch diesen Typ dargestellt werden kann. Vielleicht = 2, was kein Bool ist. Außerdem können True, False und Bool nicht in Kleinbuchstaben geschrieben werden, da sie sonst mit Sprachschlüsselwörtern in Konflikt geraten. Eine Aufzählung kann auch keinen Zeigertyp haben.
Die Regeln für Aufzählungen unterscheiden sich in C ++.
#include <iostream>
c j; //not allowed, unknown type name c before enum c{f} p; line
enum c j; //not allowed, forward declaration of enum type not allowed and variable can have an incomplete type but not when it's still a forward declaration in C++ unlike C
enum c{f, m} p;
typedef int d;
typedef int c; // not allowed in C++ as it clashes with enum c, but if just int c were used then the below usages of c j; would have to be enum c j;
[enum] c j;
enum m {n} ;
int main() {
[enum] c j;
enum d{l}; //not allowed in same scope as typedef but allowed here
d q;
m y; //simple type specifier not allowed, need elaborated type specifier enum m to refer to enum m here
p v; // not allowed, need enum p to refer to enum p
std::cout << j;
}
Aufzählungsvariablen in C ++ sind nicht mehr nur vorzeichenlose Ganzzahlen usw., sondern auch vom Aufzählungstyp und können nur Konstanten in der Aufzählung zugewiesen werden. Dies kann jedoch weggeworfen werden.
#include <stdio.h>
enum a {l} c;
enum d {f} ;
int main() {
c=0; // not allowed;
c=l;
c=(a)1;
c=(enum a)4;
printf("%llu", c); //4
}
Aufzählungsklassen
enum struct
ist identisch mit enum class
#include <stdio.h>
enum class a {b} c;
int main() {
printf("%llu", a::b<1) ; //not allowed
printf("%llu", (int)a::b<1) ;
printf("%llu", a::b<(a)1) ;
printf("%llu", a::b<(enum a)1);
printf("%llu", a::b<(enum class a)1) ; //not allowed
printf("%llu", b<(enum a)1); //not allowed
}
Der Bereichsauflösungsoperator kann weiterhin für Aufzählungen ohne Gültigkeitsbereich verwendet werden.
#include <stdio.h>
enum a: bool {l, w} ;
int main() {
enum a: bool {w, l} f;
printf("%llu", ::a::w);
}
Da w jedoch nicht als etwas anderes im Geltungsbereich definiert werden kann, gibt es keinen Unterschied zwischen ::w
und::a::w