Bagaimana cara mendefinisikan tipe enumerasi (enum) dalam C?

272

Saya tidak yakin apa sintaksis yang tepat untuk menggunakan C enum. Saya memiliki kode berikut:

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

Tapi ini tidak dikompilasi, dengan kesalahan berikut:

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

Apa yang saya lakukan salah?

bagian belakang
sumber
7
Pertanyaan bertahun-tahun, mungkin tidak ada yang akan melihat ini; tetapi mengapa ini memberikan kesalahan? Itu harus bekerja dengan baik karena dalam pertanyaan sejauh pengetahuan saya.
Utkan Gezer
2
@ Solver mengapa sintaks ini salah?
MCG
6
@ MCQ, menghapus necro'd necro: Sintaks yang disajikan dalam pertanyaan tidak salah dalam C. Ia menyatakan strategymemiliki jenis enumerasi anonim, dan menetapkan salah satu nilai yang dinyatakan dari jenis itu untuk itu. Selain itu, jika saya membungkus kode yang disajikan dalam main()fungsi yang sepele maka itu mengkompilasi baik untuk saya, bahkan tanpa peringatan, dengan gcc 4.4.7. Beberapa jawaban menyiratkan hal yang sama, meskipun tidak dalam banyak kata.
John Bollinger
5
Sebagian besar jawaban tidak mengetahui fakta bahwa dua baris kode dalam pertanyaan bukan hanya cuplikan. Mereka adalah seluruh file sumber. Jika dua baris tersebut termasuk dalam tubuh fungsi, tidak ada kesalahan. Jika mereka muncul di lingkup file, di luar deklarasi fungsi, Anda akan mendapatkan kesalahan yang ditanyakan OP (ditambah beberapa yang lain ketika saya mencobanya). Masalah mendasarnya adalah bahwa kompiler mencoba memperlakukan strategy = IMMEDIATE;sebagai deklarasi. Ini memiliki bentuk yang seharusnya legal di pra-ANSI C, tetapi di C modern itu ilegal. Tugas tidak diizinkan pada ruang lingkup file.
Keith Thompson
3
@ Solver: enum strategy { ... };mendefinisikan tipe enumerated bernama enum strategy, di mana strategytag. enum { ... } strategy;mendefinisikan jenis enumerasi anonim (tanpa tag) dan satu objek dari jenis itu bernama strategy. Keduanya legal; mereka hanya berarti hal yang berbeda.
Keith Thompson

Jawaban:

377

Mendeklarasikan variabel enum dilakukan seperti ini:

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

Namun, Anda dapat menggunakan a typedefuntuk mempersingkat deklarasi variabel, seperti:

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

Memiliki konvensi penamaan untuk membedakan antara jenis dan variabel adalah ide yang bagus:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
strategy_type my_strategy = IMMEDIATE;
RichieHindle
sumber
1
Tetapi OP menginginkan variabel tipe enum anonim
osvein
Tidak bisakah saya cukup mengetik enum MyEnum {} myVar;dan kemudian menggunakan variabel myVarsebagai berikut:myVar = SOMEENUMCONSTANT;
Mushy
451

Itu worth menunjukkan bahwa Anda tidak perlu sebuah typedef. Anda bisa melakukannya seperti berikut ini

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

Ini pertanyaan gaya apakah Anda suka typedef. Tanpanya, jika Anda ingin merujuk ke tipe enumerasi, Anda perlu menggunakannya enum strategy. Dengan itu, Anda bisa mengatakannya strategy.

Kedua cara memiliki pro dan kontra. Yang satu lebih bertele-tele, tetapi tetap ketik pengidentifikasi ke dalam tag-namespace di mana mereka tidak akan bertentangan dengan pengidentifikasi biasa (pikirkan struct statdan statfungsinya: ini juga tidak bertentangan), dan di mana Anda segera melihat bahwa itu adalah tipe. Yang lain lebih pendek, tetapi membawa pengenal tipe ke namespace biasa.

Johannes Schaub - litb
sumber
6
Itu seharusnya bukan jawaban yang diterima karena itu salah. Anda tidak dapat menggunakan strategi enum {...}; di C - Anda bisa dan harus melakukannya dalam C ++.
jelas
19
@Clearer: Kode ini berfungsi dengan baik. Berikut ini contoh yang berfungsi: ideone.com/T0YV17 Perhatikan bahwa enumkata kunci tersebut menggunakan kata kunci di kedua baris.
RichieHindle
Atau "typedef enum strategy {RANDOM, SEGERA, SEARCH} strategy_t;" dan dev menggunakan enum dapat menggunakan konvensi mana pun yang mereka inginkan.
Andy Nugent
ini berfungsi dengan sangat baik: enum strategy { RANDOM, IMMEDIATE, SEARCH }; maka ketika Anda menginginkan sebuah instance dari enum itu: `enum strategy myEnum;
user3629249
2
@AndyNugent jangan lakukan itu! * _t jenis dicadangkan oleh POSIX
osvein
58

Anda mencoba mendeklarasikan strategydua kali, dan itulah sebabnya Anda mendapatkan kesalahan di atas. Berikut ini berfungsi tanpa keluhan (dikompilasi dengan gcc -ansi -pendantic -Wall):

#include <stdio.h>

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

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

    return 0;
}

Jika alih-alih yang di atas, baris kedua diubah menjadi:

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

Dari peringatan, Anda dapat dengan mudah melihat kesalahan Anda:

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

Jadi kompilator mengambil strategy = IMMEDIATEuntuk deklarasi variabel yang disebut strategydengan tipe default int, tetapi sudah ada deklarasi variabel sebelumnya dengan nama ini.

Namun, jika Anda menempatkan tugas dalam main()fungsi, itu akan menjadi kode yang valid:

#include <stdio.h>

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

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

    return 0;
}
Tarc
sumber
48

Kapan kamu berkata

enum {RANDOM, IMMEDIATE, SEARCH} strategy;

Anda membuat variabel instan tunggal, yang disebut 'strategi' enum tanpa nama. Ini bukan hal yang sangat berguna untuk dilakukan - Anda perlu mengetik:

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

sumber
9
Mengapa ini tidak bermanfaat? Jika saya tidak peduli dengan nama jenisnya, mengapa saya harus memberikannya? Satu-satunya hal yang dimaksudkan di sini adalah memberi nama variabel, jadi dimungkinkan untuk menetapkan nilai baru padanya.
MSalters
3
Saya mengatakan itu tidak SANGAT berguna, dan saya tidak percaya itu. Tentu saja, saya tidak menggunakan pola ini dalam kode saya sendiri. YMMV.
3
@HorseSMith Enum tanpa nama tidak terlalu berguna karena Anda tidak dapat memiliki variabel lain dari tipe itu, atau parameter fungsi atau nilai pengembalian. Jika satu - satunya variabel yang Anda butuhkan, maka tidak masalah.
Bob Stein
3
Seseorang yang tidak menggunakan enum anonim tidak membuktikan bahwa mereka tidak ada gunanya. Anda tidak perlu mengetik. Beberapa pedoman kode (kernel.org/doc/Documentation/CodingStyle) bahkan tidak mendukungnya.
martinkunev
2
Jawaban ini juga menyesatkan. Jawaban Tarc adalah satu-satunya jawaban di sini.
nightpool
13

Seperti yang tertulis, tidak ada yang salah dengan kode Anda. Anda yakin belum melakukan hal seperti itu

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

Baris apa yang ditunjukkan pesan kesalahan? Ketika dikatakan "deklarasi 'strategi' sebelumnya ada di sini", apa "di sini" dan apa yang ditunjukkannya?

John Bode
sumber
6
Dia mungkin melakukannya strategy = IMMEDIATE;pada lingkup file. Tugas tidak dapat terjadi pada lingkup file di luar semua fungsi. Jadi kompiler mencoba untuk melakukan yang terbaik dari kesalahan dan mengasumsikan maksudnya int strategy = IMMEDIATE;, pada titik mana konflik terjadi.
Johannes Schaub - litb
2
Ini adalah jawaban terbaik, ada begitu banyak kebingungan dalam jawaban lain itu menyakitkan.
bersantai
12

@ThoAppelsin dalam komentarnya untuk pertanyaan yang diposting benar. Cuplikan kode yang diposting di pertanyaan itu valid dan tanpa kesalahan. Kesalahan yang Anda miliki pasti karena sintaksis buruk lainnya di tempat lain dari file sumber c Anda. enum{a,b,c};mendefinisikan tiga konstanta simbolik ( a, bdan c) yang bilangan bulat dengan nilai-nilai 0, 1dan 2masing - masing, tetapi ketika kita menggunakannya enumadalah karena kita biasanya tidak peduli dengan nilai integer spesifik, kita lebih peduli tentang makna nama konstanta simbolik. Ini berarti Anda dapat memiliki ini:

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

dan ini akan menampilkan 1.

Ini juga akan valid:

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

dan akan menampilkan yang sama seperti sebelumnya.

Jika kamu melakukan ini:

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

Anda akan memiliki kesalahan, tetapi jika Anda melakukan ini:

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

Anda tidak akan memiliki kesalahan.

kamu bisa melakukan ini:

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

dan aaakan menjadi variabel integer dengan nilai 0. tetapi Anda juga bisa melakukan ini:

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

dan akan memiliki efek yang sama (yaitu, aamenjadi intdengan 0nilai).

Anda juga dapat melakukan ini:

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

dan aaakan intdengan nilai 7.

karena Anda tidak dapat mengulangi definisi konstan simbolis dengan penggunaan enum, seperti yang telah saya katakan sebelumnya, Anda harus menggunakan tag jika Anda ingin mendeklarasikan intvars dengan menggunakan enum:

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

penggunaannya typedefadalah untuk melindungi Anda dari penulisan setiap kali enum tag1mendefinisikan variabel. Dengan typedefAnda cukup mengetik Tag1:

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

Anda juga dapat memiliki:

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

Hal terakhir yang dikatakan adalah bahwa karena kita berbicara tentang konstanta simbolik yang ditentukan, lebih baik menggunakan huruf kapital saat menggunakan enum, misalnya:

enum {A,B,C};

dari pada

enum {a,b,c};
roggc
sumber
10

Perlu disebutkan bahwa dalam C ++ Anda dapat menggunakan "enum" untuk mendefinisikan tipe baru tanpa memerlukan pernyataan typedef.

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

Saya menemukan pendekatan ini jauh lebih ramah.

[edit - status C ++ yang diklarifikasi - Saya sudah memilikinya pada awalnya, lalu dihapus!]

Roddy
sumber
Ya, Anda seharusnya tidak pernah menggunakan typedef dengan enums (atau struct, unions dll) di C ++.
17
Pertanyaan ini untuk C, bukan untuk C ++. Di C, kode di atas tidak valid - Anda juga harus menggunakan typedef, atau menentukan enumdalam deklarasi variabel juga: enum Strategy {RANDOM, IMMEDIATE, SEARCH}; ... enum Strategy myStrategy = SEGERA;
Pavel Minaev
@ Pavel - salahku. Saya memiliki "di C ++" pada awalnya, kemudian melakukan beberapa penelitian yang tampaknya bertentangan dengan itu.
Roddy
@Pavel Saya pikir itu harus menjadi jawaban terpisah yang menjelaskan manfaat menggunakan enum Strategy. Saya melakukan itu, lihat di bawah.
Johannes Schaub - litb
8

Tampaknya ada kebingungan tentang deklarasi tersebut.

Ketika strategydatang sebelumnya {RANDOM, IMMEDIATE, SEARCH}sebagai berikut,

enum strategy {RANDOM, IMMEDIATE, SEARCH};

Anda membuat jenis baru bernama enum strategy. Namun, ketika mendeklarasikan variabel, Anda harus menggunakannya enum strategysendiri. Anda tidak bisa hanya menggunakan strategy. Jadi yang berikut ini tidak valid.

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

Sementara, yang berikut ini valid

enum strategy {RANDOM, IMMEDIATE, SEARCH};

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

Ketika strategydatang setelah {RANDOM, IMMEDIATE, SEARCH}, Anda membuat enum anonim dan kemudian mendeklarasikan strategysebagai variabel jenis itu.

Jadi sekarang, Anda dapat melakukan sesuatu seperti

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

Namun, Anda tidak dapat mendeklarasikan variabel jenis apa pun enum {RANDOM, IMMEDIATE, SEARCH}karena Anda belum pernah menamainya. Jadi yang berikut ini tidak valid

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

Anda dapat menggabungkan kedua definisi juga

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

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

Typedef seperti yang disebutkan sebelumnya digunakan untuk membuat deklarasi variabel yang lebih pendek.

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;

Sekarang Anda telah memberitahu kompiler yang enum {RANDOM, IMMEDIATE, SEARCH}bersinonim strategy. Jadi sekarang Anda bisa bebas menggunakan strategysebagai tipe variabel. Anda tidak perlu mengetik enum strategylagi. Yang berikut ini valid sekarang

strategy x = RANDOM;

Anda juga dapat menggabungkan Typedef bersama dengan nama enum untuk mendapatkannya

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

Tidak banyak keuntungan menggunakan metode ini selain dari fakta bahwa Anda sekarang dapat menggunakan strategydan enum strategyNamesecara bergantian.

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

enum strategyName a = RANDOM;
strategy b = SEARCH;
Membingungkan
sumber
1
Jawaban yang bagus Saya juga menemukan definisi enum yang ditulis seperti ini: typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategyatau typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy_type. Apakah ada kelebihan di atas typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy? Apakah Anda mempertimbangkan untuk menambahkan ini ke jawaban Anda, untuk kelengkapan?
tanggal
Iya. Saya mengubah jawaban saya. Sesuai pengetahuan saya, tidak ada keuntungan utama dalam kasus umum.
Bingung
2
Hebat, jawaban Anda mencakup semuanya sekarang, terima kasih. Sayang sekali itu jauh di bawah daftar jawaban, tidak sedikit karena itu secara eksplisit membahas pertanyaan awal, dengan penjelasan yang tepat.
umumnya
2

Jika Anda menyatakan nama untuk pencacahan, tidak akan terjadi kesalahan.

Jika tidak dinyatakan, Anda harus menggunakan typedef:

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

Itu tidak akan menampilkan kesalahan ...

Peter Mortensen
sumber
2

Konstruksi favorit saya dan hanya digunakan selalu:

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

Saya percaya ini akan menghapus masalah Anda. Menggunakan tipe baru dari sudut pandang saya opsi yang tepat.

Sany
sumber
1

Jawaban Tarc adalah yang terbaik.

Sebagian besar diskusi enum adalah herring merah.

Bandingkan cuplikan kode ini: -

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

pemberian yang mana

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

dengan ini yang mengkompilasi tanpa masalah.

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

Variabel strategyperlu diatur pada deklarasi atau di dalam suatu fungsi dll. Anda tidak dapat menulis perangkat lunak yang sewenang-wenang - khususnya penugasan - pada lingkup global.

Fakta bahwa ia menggunakan enum {RANDOM, SEGERA, SEARCH} alih-alih hanya relevan dengan tingkat bahwa hal itu membingungkan orang-orang yang tidak dapat melihat lebih dari itu. Pesan kesalahan redefinisi dalam pertanyaan menunjukkan bahwa ini adalah kesalahan yang dilakukan penulis.

Jadi sekarang Anda harus dapat melihat mengapa contoh pertama di bawah ini salah dan tiga lainnya baik-baik saja.

Contoh 1. SALAH!

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

Contoh 2. KANAN.

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

Contoh 3. BENAR.

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

Contoh 4. BENAR.

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

Jika Anda memiliki program yang berfungsi, Anda hanya dapat menempelkan potongan-potongan ini ke dalam program Anda dan melihat bahwa beberapa kompilasi dan beberapa tidak.

Ivan
sumber
0

Saya mencoba dengan gcc dan muncul untuk kebutuhan saya, saya terpaksa menggunakan alternatif terakhir, untuk mengkompilasi dengan kesalahan keluar.

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

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 \n", now);
printf("Sate before = %d \n\n", before);
gg cg
sumber
newadalah pilihan pengidentifikasi yang buruk dalam keluarga C karena merupakan operator dalam C ++.
jww
0

C

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

Deklarasi yang bertindak sebagai definisi tentatif dari bilangan bulat yang ditandatangani sdengan tipe lengkap dan deklarasi yang bertindak sebagai definisi tentatif bilangan bulat yang ditandatangani qdengan tipe tidak lengkap dalam cakupan (yang menyelesaikan ke tipe lengkap dalam lingkup karena definisi tipe hadir di mana saja di ruang lingkup) (seperti definisi tentatif, pengidentifikasi qdan sdapat dideklarasikan ulang dengan versi yang tidak lengkap atau lengkap dari jenis yang sama intatau enum stuffbeberapa kali tetapi hanya didefinisikan satu kali dalam ruang lingkup yaitu int q = 3; dan hanya dapat didefinisikan ulang dalam subscope, dan hanya dapat digunakan setelah definisi). Anda juga hanya dapat menggunakan tipe lengkap enum stuffsekali dalam lingkup karena berfungsi sebagai definisi tipe.

Definisi tipe enumerasi kompiler enum stuffjuga dibuat hadir di lingkup file (dapat digunakan sebelum dan di bawah) serta deklarasi tipe maju (tipe enum stuffdapat memiliki beberapa deklarasi tetapi hanya satu definisi / penyelesaian dalam lingkup dan dapat didefinisikan ulang dalam subskop) . Hal ini juga bertindak sebagai direktif kompiler untuk mengganti adengan nilai p 0, bdengan -4, cdengan 5, ddengan -2, edengan -3, fdengan -1dan gdengan -2di lingkup saat ini. Konstanta enumerasi sekarang berlaku setelah definisi sampai redefinisi berikutnya dalam enum berbeda yang tidak dapat berada pada tingkat cakupan yang sama.

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 

Tag namespace yang digunakan bersama oleh enum, struct dan union terpisah dan harus diawali dengan jenis kata kunci (enum, struct atau union) dalam C yaitu setelah enum a {a} b, enum a charus digunakan dan tidak a c. Karena tag namespace terpisah ke namespace pengenal, enum a {a} bdiizinkan tetapi enum a {a, b} bbukan karena konstanta berada dalam namespace yang sama dengan pengidentifikasi variabel, namespace pengidentifikasi. typedef enum a {a,b} bjuga tidak diizinkan karena nama-typedef adalah bagian dari namespace pengenal.

Jenis enum booldan konstanta mengikuti pola berikut dalam 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 |
+-----------+-----+---------------+------+

Ini mengkompilasi dengan baik di 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 ++

Di C ++, enum dapat memiliki tipe

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

Dalam situasi ini, konstanta dan pengidentifikasi semua memiliki tipe yang sama, bool, dan kesalahan akan terjadi jika angka tidak dapat diwakili oleh tipe itu. Mungkin = 2, yang bukan bool. Juga, True, False dan Bool tidak boleh huruf kecil jika tidak akan berbenturan dengan kata kunci bahasa. Enum juga tidak dapat memiliki tipe pointer.

Aturan untuk enum berbeda dalam 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;
}

Enum variabel dalam C ++ tidak lagi hanya unsigned integers dll, mereka juga bertipe enum dan hanya dapat diberikan konstanta dalam enum. Namun ini bisa dibuang.

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

Kelas Enum

enum struct identik dengan 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 resolusi ruang lingkup masih dapat digunakan untuk enum non-cakupan.

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

Tetapi karena w tidak dapat didefinisikan sebagai sesuatu yang lain dalam ruang lingkup, tidak ada perbedaan antara ::wdan::a::w

Lewis Kelsey
sumber