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?
strategy
memiliki jenis enumerasi anonim, dan menetapkan salah satu nilai yang dinyatakan dari jenis itu untuk itu. Selain itu, jika saya membungkus kode yang disajikan dalammain()
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.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.enum strategy { ... };
mendefinisikan tipe enumerated bernamaenum strategy
, di manastrategy
tag.enum { ... } strategy;
mendefinisikan jenis enumerasi anonim (tanpa tag) dan satu objek dari jenis itu bernamastrategy
. Keduanya legal; mereka hanya berarti hal yang berbeda.Jawaban:
Mendeklarasikan variabel enum dilakukan seperti ini:
Namun, Anda dapat menggunakan a
typedef
untuk mempersingkat deklarasi variabel, seperti:Memiliki konvensi penamaan untuk membedakan antara jenis dan variabel adalah ide yang bagus:
sumber
enum MyEnum {} myVar;
dan kemudian menggunakan variabelmyVar
sebagai berikut:myVar = SOMEENUMCONSTANT;
Itu worth menunjukkan bahwa Anda tidak perlu sebuah
typedef
. Anda bisa melakukannya seperti berikut iniIni pertanyaan gaya apakah Anda suka
typedef
. Tanpanya, jika Anda ingin merujuk ke tipe enumerasi, Anda perlu menggunakannyaenum strategy
. Dengan itu, Anda bisa mengatakannyastrategy
.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 stat
danstat
fungsinya: 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.sumber
enum
kata kunci tersebut menggunakan kata kunci di kedua baris.enum strategy { RANDOM, IMMEDIATE, SEARCH };
maka ketika Anda menginginkan sebuah instance dari enum itu: `enum strategy myEnum;Anda mencoba mendeklarasikan
strategy
dua kali, dan itulah sebabnya Anda mendapatkan kesalahan di atas. Berikut ini berfungsi tanpa keluhan (dikompilasi dengangcc -ansi -pendantic -Wall
):Jika alih-alih yang di atas, baris kedua diubah menjadi:
Dari peringatan, Anda dapat dengan mudah melihat kesalahan Anda:
Jadi kompilator mengambil
strategy = IMMEDIATE
untuk deklarasi variabel yang disebutstrategy
dengan tipe defaultint
, tetapi sudah ada deklarasi variabel sebelumnya dengan nama ini.Namun, jika Anda menempatkan tugas dalam
main()
fungsi, itu akan menjadi kode yang valid:sumber
Kapan kamu berkata
Anda membuat variabel instan tunggal, yang disebut 'strategi' enum tanpa nama. Ini bukan hal yang sangat berguna untuk dilakukan - Anda perlu mengetik:
sumber
Seperti yang tertulis, tidak ada yang salah dengan kode Anda. Anda yakin belum melakukan hal seperti itu
Baris apa yang ditunjukkan pesan kesalahan? Ketika dikatakan "deklarasi 'strategi' sebelumnya ada di sini", apa "di sini" dan apa yang ditunjukkannya?
sumber
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 maksudnyaint strategy = IMMEDIATE;
, pada titik mana konflik terjadi.@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
,b
danc
) yang bilangan bulat dengan nilai-nilai0
,1
dan2
masing - masing, tetapi ketika kita menggunakannyaenum
adalah karena kita biasanya tidak peduli dengan nilai integer spesifik, kita lebih peduli tentang makna nama konstanta simbolik. Ini berarti Anda dapat memiliki ini:dan ini akan menampilkan
1
.Ini juga akan valid:
dan akan menampilkan yang sama seperti sebelumnya.
Jika kamu melakukan ini:
Anda akan memiliki kesalahan, tetapi jika Anda melakukan ini:
Anda tidak akan memiliki kesalahan.
kamu bisa melakukan ini:
dan
aa
akan menjadi variabel integer dengan nilai0
. tetapi Anda juga bisa melakukan ini:dan akan memiliki efek yang sama (yaitu,
aa
menjadiint
dengan0
nilai).Anda juga dapat melakukan ini:
dan
aa
akanint
dengan nilai7
.karena Anda tidak dapat mengulangi definisi konstan simbolis dengan penggunaan
enum
, seperti yang telah saya katakan sebelumnya, Anda harus menggunakan tag jika Anda ingin mendeklarasikanint
vars dengan menggunakanenum
:penggunaannya
typedef
adalah untuk melindungi Anda dari penulisan setiap kalienum tag1
mendefinisikan variabel. Dengantypedef
Anda cukup mengetikTag1
:Anda juga dapat memiliki:
Hal terakhir yang dikatakan adalah bahwa karena kita berbicara tentang konstanta simbolik yang ditentukan, lebih baik menggunakan huruf kapital saat menggunakan
enum
, misalnya:dari pada
sumber
Perlu disebutkan bahwa dalam C ++ Anda dapat menggunakan "enum" untuk mendefinisikan tipe baru tanpa memerlukan pernyataan typedef.
Saya menemukan pendekatan ini jauh lebih ramah.
[edit - status C ++ yang diklarifikasi - Saya sudah memilikinya pada awalnya, lalu dihapus!]
sumber
typedef
, atau menentukanenum
dalam deklarasi variabel juga: enum Strategy {RANDOM, IMMEDIATE, SEARCH}; ... enum Strategy myStrategy = SEGERA;enum Strategy
. Saya melakukan itu, lihat di bawah.Tampaknya ada kebingungan tentang deklarasi tersebut.
Ketika
strategy
datang sebelumnya{RANDOM, IMMEDIATE, SEARCH}
sebagai berikut,Anda membuat jenis baru bernama
enum strategy
. Namun, ketika mendeklarasikan variabel, Anda harus menggunakannyaenum strategy
sendiri. Anda tidak bisa hanya menggunakanstrategy
. Jadi yang berikut ini tidak valid.Sementara, yang berikut ini valid
Ketika
strategy
datang setelah{RANDOM, IMMEDIATE, SEARCH}
, Anda membuat enum anonim dan kemudian mendeklarasikanstrategy
sebagai variabel jenis itu.Jadi sekarang, Anda dapat melakukan sesuatu seperti
Namun, Anda tidak dapat mendeklarasikan variabel jenis apa pun
enum {RANDOM, IMMEDIATE, SEARCH}
karena Anda belum pernah menamainya. Jadi yang berikut ini tidak validAnda dapat menggabungkan kedua definisi juga
Typedef
seperti yang disebutkan sebelumnya digunakan untuk membuat deklarasi variabel yang lebih pendek.Sekarang Anda telah memberitahu kompiler yang
enum {RANDOM, IMMEDIATE, SEARCH}
bersinonimstrategy
. Jadi sekarang Anda bisa bebas menggunakanstrategy
sebagai tipe variabel. Anda tidak perlu mengetikenum strategy
lagi. Yang berikut ini valid sekarangAnda juga dapat menggabungkan Typedef bersama dengan nama enum untuk mendapatkannya
Tidak banyak keuntungan menggunakan metode ini selain dari fakta bahwa Anda sekarang dapat menggunakan
strategy
danenum strategyName
secara bergantian.sumber
typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy
atautypedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy_type
. Apakah ada kelebihan di atastypedef enum {RANDOM, IMMEDIATE, SEARCH} strategy
? Apakah Anda mempertimbangkan untuk menambahkan ini ke jawaban Anda, untuk kelengkapan?Jika Anda menyatakan nama untuk pencacahan, tidak akan terjadi kesalahan.
Jika tidak dinyatakan, Anda harus menggunakan
typedef
:Itu tidak akan menampilkan kesalahan ...
sumber
Konstruksi favorit saya dan hanya digunakan selalu:
Saya percaya ini akan menghapus masalah Anda. Menggunakan tipe baru dari sudut pandang saya opsi yang tepat.
sumber
Jawaban Tarc adalah yang terbaik.
Sebagian besar diskusi enum adalah herring merah.
Bandingkan cuplikan kode ini: -
pemberian yang mana
dengan ini yang mengkompilasi tanpa masalah.
Variabel
strategy
perlu 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!
Contoh 2. KANAN.
Contoh 3. BENAR.
Contoh 4. BENAR.
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.
sumber
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 ;
sumber
new
adalah pilihan pengidentifikasi yang buruk dalam keluarga C karena merupakan operator dalam C ++.C
Deklarasi yang bertindak sebagai definisi tentatif dari bilangan bulat yang ditandatangani
s
dengan tipe lengkap dan deklarasi yang bertindak sebagai definisi tentatif bilangan bulat yang ditandatanganiq
dengan 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, pengidentifikasiq
dans
dapat dideklarasikan ulang dengan versi yang tidak lengkap atau lengkap dari jenis yang samaint
atauenum stuff
beberapa 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 lengkapenum stuff
sekali dalam lingkup karena berfungsi sebagai definisi tipe.Definisi tipe enumerasi kompiler
enum stuff
juga dibuat hadir di lingkup file (dapat digunakan sebelum dan di bawah) serta deklarasi tipe maju (tipeenum stuff
dapat memiliki beberapa deklarasi tetapi hanya satu definisi / penyelesaian dalam lingkup dan dapat didefinisikan ulang dalam subskop) . Hal ini juga bertindak sebagai direktif kompiler untuk menggantia
dengan nilai p0
,b
dengan-4
,c
dengan5
,d
dengan-2
,e
dengan-3
,f
dengan-1
dang
dengan-2
di lingkup saat ini. Konstanta enumerasi sekarang berlaku setelah definisi sampai redefinisi berikutnya dalam enum berbeda yang tidak dapat berada pada tingkat cakupan yang sama.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 c
harus digunakan dan tidaka c
. Karena tag namespace terpisah ke namespace pengenal,enum a {a} b
diizinkan tetapienum a {a, b} b
bukan karena konstanta berada dalam namespace yang sama dengan pengidentifikasi variabel, namespace pengidentifikasi.typedef enum a {a,b} b
juga tidak diizinkan karena nama-typedef adalah bagian dari namespace pengenal.Jenis
enum bool
dan konstanta mengikuti pola berikut dalam C:Ini mengkompilasi dengan baik di C:
C ++
Di C ++, enum dapat memiliki tipe
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 ++.
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.
Kelas Enum
enum struct
identik denganenum class
Operator resolusi ruang lingkup masih dapat digunakan untuk enum non-cakupan.
Tetapi karena w tidak dapat didefinisikan sebagai sesuatu yang lain dalam ruang lingkup, tidak ada perbedaan antara
::w
dan::a::w
sumber