I'm tidak yakin apa sintaks yang tepat untuk menggunakan C enums. Saya punya kode berikut:
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
Tapi ini tidak mengkompilasi, dengan error berikut:
error: conflicting types for ‘strategy’
error: previous declaration of ‘strategy’ was here
Apa yang saya lakukan salah?
It's worth menunjukkan bahwa anda don't perlu a typedef
. Anda hanya dapat melakukannya seperti berikut
enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;
It's gaya pertanyaan apakah anda lebih suka typedef
. Tanpa itu, jika anda ingin merujuk ke tipe enumerasi, anda perlu menggunakan enum strategi
. Dengan itu, anda hanya bisa mengatakan strategi
.
Keduanya memiliki pro dan kontra. Yang satu ini lebih bertele-tele, namun tetap jenis pengenal ke tag-namespace di mana mereka tidak't konflik dengan biasa pengenal (berpikir struct stat
dan stat
fungsi: ini don't konflik baik), dan di mana anda akan segera melihat bahwa itu's jenis. Lain yang lebih pendek, tapi membawa jenis pengenal ke biasa namespace.
Mendeklarasikan enum variabel ini dilakukan seperti ini:
enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy my_strategy = IMMEDIATE;
Namun, anda dapat menggunakan typedef
untuk 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 baik:
typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
strategy_type my_strategy = IMMEDIATE;
Anda're berusaha untuk menyatakan strategi
dua kali, dan yang's mengapa anda're mendapatkan kesalahan di atas. Berikut bekerja tanpa keluhan (dikompilasi dengan gcc -ansi -pendantic -Dinding`):
#include <stdio.h>
enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;
int main(int argc, char** argv){
printf("strategy: %d\n", strategy);
return 0;
}
Jika bukan di atas, baris kedua diubah menjadi:
...
enum { RANDOM, IMMEDIATE, SEARCH } strategy;
strategy = IMMEDIATE;
...
Dari peringatan, anda bisa 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
Sehingga penyusun mengambil strategi = LANGSUNG
untuk deklarasi variabel yang disebut strategi
dengan tipe default int
, tapi sudah ada sebelumnya deklarasi variabel dengan nama ini.
Namun, jika anda menempatkan tugas di main()
fungsi, itu akan menjadi sebuah 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;
}
Ketika anda mengatakan
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
anda membuat satu contoh variabel, disebut 'strategi' tanpa nama enum. Ini bukan hal yang sangat berguna untuk melakukan - anda perlu typedef:
typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType;
StrategyType strategy = IMMEDIATE;
Seperti yang tertulis, ada's tidak ada yang salah dengan kode anda. Apakah anda yakin anda ingin't melakukan sesuatu seperti
int strategy;
...
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
Apa garis apakah pesan kesalahan yang menunjukkan? Ketika itu mengatakan "sebelumnya deklarasi 'strategi' di sini" apa's "di sini" dan apa yang ia lihat?
@ThoAppelsin dalam komentarnya untuk pertanyaan yang diposting adalah benar. Cuplikan kode yang diposting di pertanyaan ini adalah valid dan tidak ada kesalahan. Kesalahan anda harus menjadi buruk lainnya karena sintaks di tempat lain anda c source file. enum{a,b,c};
mendefinisikan tiga simbolis konstanta (a
, b
dan c
) yang adalah bilangan bulat dengan nilai-nilai 0
,1
dan 2
masing-masing, tapi ketika kita menggunakan enum
adalah karena kita don't biasanya peduli tentang nilai integer tertentu, kami lebih peduli tentang makna simbolik nama konstan.
Ini berarti anda dapat memiliki ini:
#include <stdio.h>
enum {a,b,c};
int main(){
printf("%d\n",b);
return 0;
}
dan ini akan keluaran 1
.
Ini juga akan berlaku:
#include <stdio.h>
enum {a,b,c};
int bb=b;
int main(){
printf("%d\n",bb);
return 0;
}
dan akan menghasilkan output yang sama seperti sebelumnya.
Jika anda melakukan hal ini:
enum {a,b,c};
enum {a,b,c};
anda akan memiliki kesalahan, tetapi jika anda melakukan hal ini:
enum alfa{a,b,c};
enum alfa;
anda tidak akan memiliki kesalahan.
anda dapat melakukan ini:
enum {a,b,c};
int aa=a;
dan aa
akan menjadi sebuah variabel integer dengan nilai 0
. tapi anda juga dapat melakukan ini:
enum {a,b,c} aa= a;
dan akan memiliki efek yang sama (yaitu, aa
menjadi int
dengan 0
value).
anda juga dapat melakukan ini:
enum {a,b,c} aa= a;
aa= 7;
dan aa
akan int
dengan nilai 7
.
karena anda tidak bisa mengulang simbolis konstan definisi dengan menggunakan enum
, seperti yang telah saya katakan sebelumnya, anda harus menggunakan tag jika anda ingin mendeklarasikan int
vars dengan menggunakan enum
:
enum tag1 {a,b,c};
enum tag1 var1= a;
enum tag1 var2= b;
penggunaan typedef
itu adalah untuk aman anda dari menulis setiap waktu enum tag1
untuk mendefinisikan variabel. Dengan typedef
anda hanya bisa 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 untuk mengatakan itu adalah bahwa karena kita berbicara tentang didefinisikan konstanta simbolis itu adalah lebih baik untuk menggunakan huruf-huruf kapital ketika menggunakan enum
, yaitu misalnya:
enum {A,B,C};
bukan
enum {a,b,c};
It's worth menyebutkan bahwa dalam C++ anda dapat menggunakan "enum" untuk menentukan jenis baru tanpa perlu typedef pernyataan.
enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;
Saya menemukan pendekatan ini jauh lebih ramah.
[edit - diklarifikasi C++ status - aku punya ini di awalnya, kemudian dihapus!]
Sepertinya ada kebingungan tentang deklarasi.
Ketika strategi'comes sebelum
{RANDOM, LANGSUNG, PENCARIAN}` sebagai berikut,
enum strategy {RANDOM, IMMEDIATE, SEARCH};
anda adalah menciptakan jenis baru bernama enum strategi
. Namun, ketika mendeklarasikan variabel, anda perlu menggunakan enum strategi
itu sendiri. Anda tidak bisa hanya menggunakan strategi
. Jadi berikut ini adalah valid.
enum strategy {RANDOM, IMMEDIATE, SEARCH};
strategy a;
Sementara, berikut ini adalah berlaku
enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy queen = RANDOM;
enum strategy king = SEARCH;
enum strategy pawn[100];
Ketika strategi
datang setelah {RANDOM, LANGSUNG, PENCARIAN}
, anda menciptakan anonim enum dan kemudian menyatakan strategi
untuk menjadi variabel dari jenis yang.
Jadi sekarang, anda dapat melakukan sesuatu seperti
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = RANDOM;
Namun, anda tidak dapat mendeklarasikan variabel lain dari jenis enum {RANDOM, LANGSUNG, PENCARIAN}
karena anda belum pernah bernama itu. Jadi berikut adalah valid
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
enum strategy a = RANDOM;
Anda dapat menggabungkan kedua definisi yang terlalu
enum strategy {RANDOM, IMMEDIATE, SEARCH} a, b;
a = RANDOM;
b = SEARCH;
enum strategy c = IMMEDIATE;
Typedef
seperti disebutkan sebelum ini digunakan untuk menciptakan lebih pendek deklarasi variabel.
typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
Sekarang anda telah mengatakan kepada kompiler bahwa enum {RANDOM, LANGSUNG, PENCARIAN}
adalah synonomous untuk strategi
. Jadi sekarang anda dapat dengan bebas menggunakan strategi
sebagai variabel jenis. Anda don't perlu mengetik enum strategi
lagi. Berikut ini adalah berlaku
strategy x = RANDOM;
Anda juga dapat menggabungkan Typedef bersama dengan enum nama untuk mendapatkan
typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;
Ada's tidak banyak keuntungan dari menggunakan metode ini terlepas dari kenyataan bahwa anda sekarang dapat menggunakan strategi
dan enum strategyName
secara bergantian.
typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;
enum strategyName a = RANDOM;
strategy b = SEARCH;
Jika anda menyatakan nama untuk pencacahan tidak ada kesalahan yang akan terjadi.
Jika tidak dinyatakan, anda harus menggunakan typedef
:
enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
Ini tidak akan menampilkan pesan error...
Favorit saya dan hanya digunakan konstruksi selalu adalah:
typedef enum MyBestEnum { /* cukup */ BAIK = 0, /* bahkan lebih baik */ BAIK, /* ilahi */ TERBAIK };
Saya percaya bahwa ini akan menghapus masalah yang anda miliki. Dengan menggunakan jenis baru dari sudut pandang saya pilihan yang tepat.
Tarc's jawaban yang terbaik.
Banyak dari enum diskusi adalah ikan merah.
Bandingkan potongan kode ini:-
int strategy;
strategy = 1;
void some_function(void)
{
}
yang memberikan
error C2501: 'strategy' : missing storage-class or type specifiers
error C2086: 'strategy' : redefinition
dengan yang satu ini yang mengkompilasi dengan tidak ada masalah.
int strategy;
void some_function(void)
{
strategy = 1;
}
Variabel strategi
harus ditetapkan pada deklarasi atau di dalam fungsi dll. Anda tidak dapat menulis sewenang-wenang perangkat lunak - tugas khususnya di lingkup global.
Fakta bahwa ia menggunakan enum {RANDOM, LANGSUNG, PENCARIAN}, bukannya int hanya relevan untuk sejauh bahwa hal itu telah membingungkan orang-orang yang dapat't melihat di luar itu. Redefinisi pesan kesalahan pada pertanyaan menunjukkan bahwa ini adalah apa yang penulis telah melakukan kesalahan.
Jadi sekarang anda harus dapat melihat mengapa lebih dari contoh di bawah ini adalah salah dan tiga lainnya baik-baik saja.
Contoh 1. SALAH!
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
void some_function(void)
{
}
Contoh 2. BENAR.
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 kerja yang harus anda hanya dapat menyisipkan potongan ini ke dalam program anda dan lihat bahwa beberapa kompilasi dan beberapa tidak.
Saya mencoba dengan gcc dan datang dengan saya butuhkan saya dipaksa untuk menggunakan alternatif terakhir, untuk mengkompilasi dengan kesalahan.
typedef enum negara {a = 0, b = 1, c = 2} negara;
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);