Cum se definește un tip enumerat (enum) în C? (Programare, C, Enums)

lindelof a intrebat.

Nu sunt sigur care este sintaxa corectă pentru utilizarea enumerațiilor în C. Am următorul cod:

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;

Dar acesta nu compilează, cu următoarea eroare:

error: conflicting types for ‘strategy’
error: previous declaration of ‘strategy’ was here

Ce fac greșit?

Comentarii

  • Întrebare veche de ani de zile, probabil că nimeni nu va vedea asta; dar de ce dă o eroare? Ar trebui să funcționeze perfect așa cum este în întrebare, din câte știu eu. –  > Por Utkan Gezer.
  • @Solver de ce este greșită această sintaxă? –  > Por MCG.
  • @MCQ, necroind necro’d necro: Sintaxa prezentată în întrebare este nu greșită în C. Aceasta declară strategy ca având un tip enumerat anonim și îi atribuie una dintre valorile declarate ale acelui tip. Mai mult decât atât, dacă înfășor codul prezentat într-un cod altfel banal main() atunci acesta se compilează bine pentru mine, fără nici măcar un avertisment, cu gcc 4.4.7. Unele dintre răspunsuri implică același lucru, deși nu în atâtea cuvinte. –  > Por John Bollinger.
  • Cele mai multe dintre răspunsuri nu țin cont de faptul că cele două linii de cod din întrebare nu sunt doar un fragment. Ele reprezintă întregul fișier sursă. Dacă acele două linii sunt incluse în corpul unei funcții, nu există nicio eroare. Dacă ele apar în domeniul de aplicare al fișierului, în afara oricărei declarații de funcție, veți obține erorile despre care a întrebat OP (plus altele când am încercat). Problema fundamentală constă în faptul că compilatorul încearcă să trateze strategy = IMMEDIATE; ca pe o declarație. Are o formă care ar fi fost legală în C pre-ANSI C, dar în C-ul modern este ilegală. Atribuirile nu sunt permise în domeniul de aplicare al fișierelor. –  > Por Keith Thompson.
  • @Solver: enum strategy { ... }; definește un tip enumerat numit enum strategy, , unde strategy este eticheta. enum { ... } strategy; definește un tip enumerat anonim (fără etichetă) și un singur obiect de acest tip numit strategy. Ambele sunt perfect legale; doar că au semnificații diferite. –  > Por Keith Thompson.
13 răspunsuri
RichieHindle

Declararea unei variabile enum se face în felul următor:

enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy my_strategy = IMMEDIATE;

Cu toate acestea, puteți utiliza un typedef pentru a scurta declarațiile variabilei, astfel:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy my_strategy = IMMEDIATE;

A avea o convenție de denumire pentru a distinge între tipuri și variabile este o idee bună:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
strategy_type my_strategy = IMMEDIATE;

Comentarii

  • Dar OP a vrut o variabilă de tip enum anonim –  > Por osvein.
  • Nu puteam să scriu pur și simplu enum MyEnum {} myVar; și apoi să folosesc variabila myVar după cum urmează: myVar = SOMEENUMCONSTANT; –  > Por Mushy.
Johannes Schaub – litb

Merită subliniat faptul că nu trebuie să nevoie de a typedef. Puteți să faceți așa cum urmează

enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;

Este o chestiune de stil dacă preferați typedef. Fără el, dacă doriți să vă referiți la tipul de enumerare, trebuie să utilizați enum strategy. Cu el, puteți spune pur și simplu strategy.

Ambele metode au avantajele și dezavantajele lor. Cea dintâi este mai stufoasă, dar păstrează identificatorii de tip în spațiul de nume de etichetă, unde nu intră în conflict cu identificatorii obișnuiți (gândiți-vă la struct stat și la stat nici acestea nu intră în conflict) și unde se vede imediat că este vorba de un tip. Cealaltă este mai scurtă, dar aduce identificatorii de tip în spațiul de nume obișnuit.

Comentarii

  • Nu ar trebui să fie răspunsul acceptat, deoarece este greșit. Nu se poate folosi strategia enum { … }; în C — puteți și ar trebui să o faceți în C++. –  > Por Mai clar.
  • 19

  • @Clearer: Acest cod funcționează perfect. Iată un exemplu funcțional: ideone.com/T0YV17 Rețineți că utilizează enum pe ambele linii. –  > Por RichieHindle.
  • Sau „typedef enum strategy { RANDOM, IMMEDIATE, SEARCH } strategy_t;”, iar dezvoltatorul care folosește enum-ul poate folosi orice convenție dorește. –  > Por Andy Nugent.
  • acest lucru funcționează excelent: enum strategy { RANDOM, IMMEDIATE, SEARCH }; apoi, când doriți o instanță a acelui enum: `enum strategy myEnum; –  > Por utilizator3629249.
  • @AndyNugent nu faceți asta! Tipurile *_t sunt rezervate de POSIX –  > Por osvein.
Tarc

Încerci să declari strategy de două ori și de aceea primești eroarea de mai sus. Următorul lucru funcționează fără nicio plângere (compilat cu gcc -ansi -pedantic -Wall):

#include <stdio.h>

enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;

int main(int argc, char** argv){
    printf("strategy: %d
", strategy);

    return 0;
}

Dacă în loc de cele de mai sus, a doua linie ar fi fost schimbată în:

...
enum { RANDOM, IMMEDIATE, SEARCH } strategy;
strategy = IMMEDIATE;
...

Din avertismente, ați putea vedea cu ușurință greșeala dumneavoastră:

enums.c:5:1: warning: data definition has no type or storage class [enabled by default]
enums.c:5:1: warning: type defaults to ‘int’ in declaration of ‘strategy’ [-Wimplicit-int]
enums.c:5:1: error: conflicting types for ‘strategy’
enums.c:4:36: note: previous declaration of ‘strategy’ was here

Deci compilatorul a luat strategy = IMMEDIATE pentru o declarație a unei variabile numite strategy cu tipul implicit int, , dar exista deja o declarație anterioară a unei variabile cu acest nume.

Cu toate acestea, dacă ați plasat atribuirea în cadrul secțiunii main() funcție, ar fi un cod valid:

#include <stdio.h>

enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;

int main(int argc, char** argv){
    strategy=SEARCH;
    printf("strategy: %d
", strategy);

    return 0;
}

anon

Când spuneți

enum {RANDOM, IMMEDIATE, SEARCH} strategy;

creați o singură variabilă de instanță, numită „strategy” a unui enum fără nume. Acesta nu este un lucru foarte util de făcut – aveți nevoie de un typedef:

typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType; 
StrategyType strategy = IMMEDIATE;

Comentarii

  • De ce nu este util? Dacă nu-mi pasă de numele tipului, de ce ar trebui să-i dau unul? Singurul lucru pe care s-a urmărit aici a fost să se dea un nume variabilei, astfel încât să fie posibilă atribuirea de noi valori acesteia. –  > Por MSalters.
  • Am spus că nu este FOARTE util și nu cred că este. Cu siguranță, eu nu folosesc acest model în propriul meu cod. YMMV. – anon
  • @HorseSMith Un enum fără nume nu este foarte util, deoarece nu puteți avea nicio altă variabilă de acest tip, sau parametru de funcție sau valoare de retur. În cazul în care o variabilă este tot ce aveți nevoie, atunci este în regulă. –  > Por Bob Stein.
  • Faptul că cineva nu folosește enumerații anonime nu dovedește că acestea nu au nicio utilitate. Nu aveți nevoie de typedef. Unele ghiduri de codare (kernel.org/doc/Documentation/CodingStyle) chiar o descurajează. –  > Por martinkunev.
  • Acest răspuns este de asemenea înșelător. Răspunsul lui Tarc este singurul corect aici. –  > Por nightpool.
John Bode

Așa cum este scris, nu este nimic în neregulă cu codul tău. Sunteți sigur că nu ați făcut ceva de genul

int strategy;
...
enum {RANDOM, IMMEDIATE, SEARCH} strategy;

Către ce linii indică mesajele de eroare? Când se spune „declarația anterioară a ‘strategy’ a fost aici”, ce este „aici” și ce arată?

Comentarii

  • Probabil că a făcut strategy = IMMEDIATE; la file-scope. O atribuire nu se poate întâmpla la file-scope în afara tuturor funcțiilor. Așa că compilatorul a încercat să scoată ce e mai bun din eroare și a presupus că a vrut să spună int strategy = IMMEDIATE;, , moment în care a apărut conflictul. –  > Por Johannes Schaub – litb.
  • Acesta este cel mai bun răspuns, există atât de multă confuzie în celelalte răspunsuri încât este dureros. –  > Por unwind.
Roddy

Merită să menționăm că în C++ puteți utiliza „enum” pentru a defini un nou tip fără a avea nevoie de o declarație typedef.

enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;

Consider că această abordare este mult mai prietenoasă.

[editare – am clarificat statutul C++ – am avut acest lucru inițial, apoi l-am eliminat!]

Comentarii

  • Da, nu ar trebui să folosiți niciodată typedef cu enums (sau structs, unions etc.) în C++. – anon
  • 17

  • Această întrebare este pentru C, nu pentru C++. În C, codul de mai sus nu este valid – fie trebuie să folosiți typedef, , fie să specificați enum și în declarația variabilei: enum Strategy {RANDOM, IMMEDIATE, SEARCH}; … enum Strategy myStrategy = IMMEDIATE; – –  > Por Pavel Minaev.
  • @pavel – greșeala mea. Inițial am avut „în C++”, apoi am făcut niște cercetări care păreau să contrazică acest lucru. –  > Por Roddy.
  • @Pavel Cred că ar trebui să fie un răspuns separat care să descrie avantajele utilizării enum Strategy. Am făcut asta, vezi mai jos. –  > Por Johannes Schaub – litb.
roggc

@ThoAppelsin în comentariul său la întrebarea postată are dreptate. Fragmentul de cod postat în întrebare este valid și fără erori. Eroarea pe care o aveți trebuie să fie din cauza altei sintaxe greșite în orice alt loc din fișierul sursă c. enum{a,b,c}; definește trei constante simbolice (a, , b și c) care sunt numere întregi cu valorile 0,1 și 2 respectiv, dar când folosim enum este pentru că, de obicei, nu ne interesează valoarea întreagă specifică, ci ne interesează mai mult semnificația numelui simbolic al constantei. Aceasta înseamnă că puteți avea acest lucru:

#include <stdio.h>
enum {a,b,c};
int main(){
  printf("%d
",b);
  return 0;
}

iar acest lucru va produce 1.

De asemenea, aceasta va fi valabilă:

#include <stdio.h>
enum {a,b,c};
int bb=b;
int main(){
  printf("%d
",bb);
  return 0;
}

și va produce același rezultat ca înainte.

Dacă faceți acest lucru:

enum {a,b,c};
enum {a,b,c};

veți avea o eroare, dar dacă faceți acest lucru:

enum alfa{a,b,c};
enum alfa;

nu veți avea nicio eroare.

puteți face acest lucru:

enum {a,b,c};
int aa=a;

și aa va fi o variabilă întreagă cu valoarea 0. dar puteți face și așa:

enum {a,b,c} aa= a;

și va avea același efect (adică, aa fiind un int cu 0 valoare).

puteți face și acest lucru:

enum {a,b,c} aa= a;
aa= 7;

și aa va fi int cu valoare 7.

pentru că nu puteți repeta definiția unei constante simbolice cu ajutorul lui enum, , așa cum am spus anterior, trebuie să folosiți tag-uri dacă doriți să declarați int vars cu ajutorul lui enum:

enum tag1 {a,b,c};
enum tag1 var1= a;
enum tag1 var2= b;

utilizarea lui typedef are rolul de a vă feri de a scrie de fiecare dată enum tag1 pentru a defini o variabilă. Cu typedef puteți tasta pur și simplu Tag1:

typedef enum {a,b,c} Tag1;
Tag1 var1= a;
Tag1 var2= b;

De asemenea, puteți avea:

typedef enum tag1{a,b,c}Tag1;
Tag1 var1= a;
enum tag1 var2= b;

Ultimul lucru pe care trebuie să-l spunem este că, din moment ce vorbim despre constante simbolice definite, este mai bine să folosim litere majuscule atunci când folosim enum, , adică, de exemplu:

enum {A,B,C};

în loc de

enum {a,b,c};

Confuzie

Se pare că există o confuzie în legătură cu declarația.

Când strategyvine înainte de {RANDOM, IMMEDIATE, SEARCH} ca în cazul următor,

enum strategy {RANDOM, IMMEDIATE, SEARCH};

creați un nou tip numit enum strategy. Cu toate acestea, atunci când declarați variabila, trebuie să utilizați enum strategy în sine. Nu puteți utiliza doar strategy. Deci, următoarea formulare nu este valabilă.

enum strategy {RANDOM, IMMEDIATE, SEARCH};
strategy a;

În timp ce următorul lucru este valabil

enum strategy {RANDOM, IMMEDIATE, SEARCH};

enum strategy queen = RANDOM;
enum strategy king = SEARCH;
enum strategy pawn[100];

Când strategy vine după {RANDOM, IMMEDIATE, SEARCH}, , creați un enum anonim și apoi declarați strategy ca fiind o variabilă de acest tip.

Astfel, acum puteți face ceva de genul

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = RANDOM;

Cu toate acestea, nu puteți declara nicio altă variabilă de tip enum {RANDOM, IMMEDIATE, SEARCH} deoarece nu ați numit-o niciodată. Așadar, următorul lucru nu este valabil

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
enum strategy a = RANDOM;

De asemenea, puteți combina ambele definiții

enum strategy {RANDOM, IMMEDIATE, SEARCH} a, b;

a = RANDOM;
b = SEARCH;
enum strategy c = IMMEDIATE;

Typedef așa cum s-a menționat anterior, este utilizat pentru a crea o declarație de variabilă mai scurtă.

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;

Acum ați spus compilatorului că enum {RANDOM, IMMEDIATE, SEARCH} este sinonimă cu strategy. Deci, acum puteți folosi liber strategy ca tip de variabilă. Nu mai este nevoie să tastați enum strategy . Următoarele sunt valabile acum

strategy x = RANDOM;

De asemenea, puteți combina Typedef împreună cu numele enum pentru a obține

typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;

Nu există prea multe avantaje în utilizarea acestei metode, în afară de faptul că acum puteți folosi strategy și enum strategyName în mod interschimbabil.

typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;

enum strategyName a = RANDOM;
strategy b = SEARCH;

Comentarii

  • Un răspuns excelent. Am întâlnit și eu definiții enum scrise astfel: typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy sau typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy_type. Are acest lucru vreun avantaj față de typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy? Ați lua în considerare adăugarea acestora la răspunsul dumneavoastră, pentru a fi complet? –  > Por tjalling.
  • Da, mi-am modificat răspunsul. După cunoștințele mele, nu există niciun avantaj major în cazul general. –  > Por Confuzie.
  • Minunat, răspunsul tău acoperă totul acum, mulțumesc. Păcat că este atât de departe în lista de răspunsuri, nu în ultimul rând pentru că este explicit răspunde explicit la întrebarea inițială, cu explicații adecvate. –  > Por tjalling.
user3135028

Dacă declarați numele pentru enumerare nu va apărea nicio eroare.

Dacă nu sunt declarate, trebuie să folosiți un typedef:

enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;

Nu se va afișa o eroare…

Sany

Construcția mea preferată și singura folosită întotdeauna a fost:

typedef enum MyBestEnum
{
    /* good enough */
    GOOD = 0,
    /* even better */
    BETTER,
    /* divine */
    BEST
};

Cred că aceasta va elimina problema pe care o aveți. Utilizarea noului tip este din punctul meu de vedere opțiunea corectă.

Ivan

Răspunsul lui Tarc este cel mai bun.

O mare parte din discuția despre enum este o pistă falsă.

Comparați acest fragment de cod:-

int strategy;
strategy = 1;   
void some_function(void) 
{
}

care dă

error C2501: 'strategy' : missing storage-class or type specifiers
error C2086: 'strategy' : redefinition

cu acesta care compilează fără probleme.

int strategy;
void some_function(void) 
{
    strategy = 1;   
}

Variabila strategy trebuie să fie setată la declarare sau în interiorul unei funcții etc. Nu puteți scrie software arbitrar – în special asignări – în domeniul global.

Faptul că a folosit enum {RANDOM, IMMEDIATE, SEARCH} în loc de int este relevant doar în măsura în care a derutat oamenii care nu pot vedea dincolo de el. mesajele de eroare de redefinire din întrebare arată că asta a greșit autorul.

Așadar, acum ar trebui să puteți vedea de ce primul din exemplul de mai jos este greșit și celelalte trei sunt în regulă.

Exemplul 1. GREȘIT!

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
void some_function(void) 
{
}

Exemplul 2. CORECT.

enum {RANDOM, IMMEDIATE, SEARCH} strategy = IMMEDIATE;
void some_function(void) 
{
}

Exemplul 3. CORECT.

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
void some_function(void) 
{
    strategy = IMMEDIATE;
}

Exemplul 4. DREAPTA.

void some_function(void) 
{
    enum {RANDOM, IMMEDIATE, SEARCH} strategy;
    strategy = IMMEDIATE;
}

Dacă aveți un program funcțional, ar trebui să puteți lipi aceste fragmente în programul dvs. și să vedeți că unele se compilează și altele nu.

gg cg

Am încercat cu gcc și am ajuns la concluzia că pentru nevoia mea am fost nevoit să folosesc ultima alternativă, să compilez fără eroare.

typedef enum state {a = 0, b = 1, c = 2} state;

typedef enum state {a = 0, b = 1, c = 2} state;

typedef enum state old; // New type, alias of the state type.
typedef enum state new; // New type, alias of the state type.

new now     = a;
old before  = b;

printf("State   now = %d 
", now);
printf("Sate before = %d 

", before);

Comentarii

  • new este o alegere proastă a identificatorilor în familia C, deoarece este un operator în C++. –  > Por jww.
Lewis Kelsey

C

enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;

Declarație care acționează ca o definiție provizorie a unui număr întreg cu semn s cu tip complet și declarație care acționează ca o definiție provizorie a unui întreg cu semn q cu tip incomplet în domeniu (care se rezolvă la tipul complet în domeniu deoarece definiția tipului este prezentă oriunde în domeniu) (ca orice definiție tentativă, identificatorii q și s pot fi redeclarați cu versiunea incompletă sau completă a aceluiași tip. int sau enum stuff de mai multe ori, dar definite o singură dată în domeniul de aplicare, de exemplu, int q = 3; și pot fi redefinite numai într-un subscop, fiind utilizabile numai după definiție). De asemenea, se poate utiliza numai tipul complet de enum stuff o singură dată în domeniul de aplicare, deoarece acționează ca o definiție de tip.

O definiție de tip de enumerare a compilatorului pentru enum stuff este, de asemenea, făcută prezentă în domeniul de aplicare al fișierului (utilizabilă înainte și sub), precum și o declarație de tip forward (tipul enum stuff poate avea mai multe declarații, dar numai o singură definiție/completare în domeniul de aplicare și poate fi redefinit într-un subscop). De asemenea, acționează ca o directivă de compilare pentru a înlocui a cu rvalue 0, , b cu -4, , c cu 5, , d cu -2, , e cu -3, , f cu -1 și g cu -2 în domeniul de aplicare curent. Constantele de enumerare se aplică acum după definiție până la următoarea redefinire într-un enum diferit, care nu poate fi la același nivel de domeniu de aplicare.

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 

Spațiul de nume de etichete partajat de enum, struct și union este separat și trebuie să fie prefixat de cuvântul cheie type (enum, struct sau union) în C, adică după enum a {a} b, , enum a c trebuie să fie folosit și nu a c. Deoarece spațiul de nume al etichetelor este separat de spațiul de nume al identificatorilor, enum a {a} b este permisă, dar enum a {a, b} b nu este permisă, deoarece constantele se află în același spațiu de nume ca și identificatorii de variabile, spațiul de nume al identificatorilor. typedef enum a {a,b} b De asemenea, nu este permisă, deoarece numele tipedef fac parte din spațiul de nume al identificatorului.

Tipul de enum bool și constantele urmează următorul model în 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 |
+-----------+-----+---------------+------+

Acest lucru se compilează bine în 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++

În C++, enumerațiile pot avea un tip

enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error

În această situație, constantele și identificatorul au toate același tip, bool, și se va produce o eroare dacă un număr nu poate fi reprezentat de acest tip. Poate = 2, care nu este un bool. De asemenea, True, False și Bool nu pot fi scrise cu minuscule, altfel vor intra în conflict cu cuvintele cheie ale limbajului. De asemenea, un enum nu poate avea un tip de pointer.

Regulile pentru enumerații sunt diferite în 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;
}

Variabilele enum în C++ nu mai sunt doar numere întregi fără semn etc., ci și de tip enum și pot fi atribuite doar constantelor din enum. Totuși, acestea pot fi eliminate.

#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
}

Clase Enum

enum struct este identică cu 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
}

Operatorul de rezolvare a domeniului de aplicare poate fi utilizat în continuare pentru enum-urile fără domeniu de aplicare.

#include <stdio.h>
enum a: bool {l, w} ;
int main() {
  enum a: bool {w, l} f;
  printf("%llu", ::a::w);
}

Dar, deoarece w nu poate fi definit ca altceva în domeniu, nu există nicio diferență între ::w și ::a::w

Tags:,