С
enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;
Декларація, яка виступає як орієнтовне визначення підписаного цілого числа s
з повним типом і декларацією, яка виступає як попереднє визначення підписаного цілого числа q
з неповним типом в області дії (яка відповідає повному типу в області, оскільки визначення типу присутнє в будь-якій точці область) (як і будь-яке попереднє визначення, ідентифікатори q
і s
можуть бути передекларовані неповною або повною версією одного типу int
або enum stuff
декількома разів, але визначені лише один раз в області застосування, тобто int q = 3; і можуть бути перевизначені лише в підскопі, і корисний лише після визначення). Також ви можете використовувати лише повний тип enum stuff
одного разу в області дії, оскільки він виступає як визначення типу.
Визначення типу компілятора для компілятора enum stuff
також подається в області файлу (застосовано до і нижче), а також декларації типу прямого типу (тип enum stuff
може мати кілька декларацій, але лише одне визначення / завершення в області та може бути переосмислений у підскопі) . Вона також діє як директива компілятора , щоб замінити a
з RValue 0
, b
з -4
, c
з 5
, d
з -2
, e
з -3
, f
з , -1
і g
з -2
в поточній області. Константи перерахування тепер застосовуються після визначення до наступного перевизначення в іншому переліку, який не може бути на одному рівні області.
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
Простір імен тегів, що розділяється enum, struct та union, є окремим і повинен бути префіксований ключовим словом типу (enum, struct чи union) в C, тобто після enum a {a} b
, enum a c
повинен бути використаний, а не a c
. Оскільки простір імен тегів є окремим простором імен ідентифікаторів, enum a {a} b
дозволено, але enum a {a, b} b
це не так, оскільки константи знаходяться в тому ж просторі імен, що і змінні ідентифікатори, простір імен ідентифікаторів.typedef enum a {a,b} b
також не дозволено, оскільки назви typedef є частиною простору імен ідентифікатора.
Тип enum bool
та константи дотримуються наступної схеми в С:
+--------------+-----+-----+-----+
| 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 |
+-----------+-----+---------------+------+
Це складе штрафи на 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 ++
У C ++ перерахунки можуть мати тип
enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error
У цій ситуації константи та ідентифікатор мають один і той же тип, bool та помилка, якщо число не може бути представлене цим типом. Можливо = 2, що не бул. Крім того, True, False і Bool не можуть бути малі, інакше вони зіткнуться з мовними ключовими словами. Перерахунок також не може мати тип вказівника.
Правила для перерахунків у 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;
}
Змінні перерахунків у C ++ більше не є лише непідписаними цілими числами тощо, вони також перелічуються та можуть бути призначені лише константи в enum. Однак це може бути відкинуто.
#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
}
Енум-класи
enum struct
тотожна 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
}
Оператор роздільної здатності діапазону все ще може бути використаний для перерахунків, що не входять в рамки.
#include <stdio.h>
enum a: bool {l, w} ;
int main() {
enum a: bool {w, l} f;
printf("%llu", ::a::w);
}
Але оскільки w не може бути визначений як щось інше в області, немає різниці між ::w
і::a::w