do
enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;
Deklaracja, która działa jako wstępna definicja podpisanej liczby całkowitej s
z pełnym typem i deklaracja, która działa jako wstępna definicja podpisanej liczby całkowitej q
z niekompletnym typem w zakresie (który rozwiązuje się do pełnego typu w zakresie, ponieważ definicja typu znajduje się w dowolnym miejscu w zakres) (jak każda wstępna definicja, identyfikatory q
i s
mogą być ponownie zadeklarowane z niekompletną lub pełną wersją tego samego typu int
lub enum stuff
wiele razy, ale tylko raz zdefiniowane w zakresie, tj. int q = 3; i mogą być ponownie zdefiniowane tylko w podzakresie, oraz możliwe do użycia tylko po definicji). Możesz także użyć pełnego typu enum stuff
raz w zakresie, ponieważ działa on jak definicja typu.
Definicja typu wyliczenia kompilatora dla enum stuff
jest również obecna w zakresie pliku (użyteczne przed i poniżej), a także w deklaracji typu forward (typ enum stuff
może mieć wiele deklaracji, ale tylko jedną definicję / uzupełnienie w zakresie i może być przedefiniowany w podskopie) . Działa również jako dyrektywy kompilatora do zastąpienia a
z rvalue 0
, b
z -4
, c
z 5
, d
z -2
, e
z -3
, f
z -1
, a g
ze -2
w obecnym zakresie. Stałe wyliczenia obowiązują teraz po definicji do następnej redefinicji w innym wyliczeniu, które nie może być na tym samym poziomie zakresu.
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
Przestrzeń nazw znaczników współdzielona przez enum, struct i union jest osobna i musi być poprzedzona słowem kluczowym type (enum, struct lub union) w C, tzn. Po enum a {a} b
, enum a c
musi być używana, a nie a c
. Ponieważ przestrzeń nazw znacznika jest oddzielna od przestrzeni nazw identyfikatora, enum a {a} b
jest dozwolona, ale enum a {a, b} b
nie dlatego, że stałe znajdują się w tej samej przestrzeni nazw, co identyfikatory zmiennych, przestrzeń nazw identyfikatora. typedef enum a {a,b} b
jest również niedozwolone, ponieważ typedef-names są częścią przestrzeni nazw identyfikatora.
Typ enum bool
i stałe są zgodne z następującym wzorcem w 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 |
+-----------+-----+---------------+------+
Kompiluje się dobrze w 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 ++
W C ++ wyliczenia mogą mieć typ
enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error
W tej sytuacji wszystkie stałe i identyfikator mają ten sam typ, bool, i wystąpi błąd, jeśli liczba nie może być reprezentowana przez ten typ. Może = 2, co nie jest boolem. Również True, False i Bool nie mogą być pisane małymi literami, w przeciwnym razie będą kolidować ze słowami kluczowymi języka. Wyliczenie również nie może mieć typu wskaźnika.
Zasady wyliczania są różne w 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;
}
Zmienne wyliczające w C ++ nie są już tylko liczbami całkowitymi bez znaku itp., Są również typu wyliczeniowego i można im przypisywać tylko stałe w wyliczeniu. Można to jednak odrzucić.
#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
}
Klasy enum
enum struct
jest identyczny z 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
}
Operator rozdzielczości zakresu nadal może być używany do wyliczeń nieposiadających zasięgu.
#include <stdio.h>
enum a: bool {l, w} ;
int main() {
enum a: bool {w, l} f;
printf("%llu", ::a::w);
}
Ale ponieważ w nie można zdefiniować jako czegoś innego w zakresie, nie ma różnicy między ::w
i::a::w