2010-04-02 13 views
15

Nel codice di esempio, ho visto questo:Obiettivo C - quando "typedef" precede "enum" e quando deve essere nominato un enum?

typedef enum Ename { Bob, Mary, John} EmployeeName; 

e questo:

typedef enum {Bob, Mary, John} EmployeeName; 

e questo:

typedef enum {Bob, Mary, John}; 

ma quello compilato con successo per me era questo:

enum {Bob, Mary, John}; 

Metto quella linea in un file .h sopra la linea @interface, e poi quando I # importa quel file .h in un file .m di una classe diversa, i metodi possono vedere l'enum.

Quindi, quando sono necessarie le altre varianti?

Se potessi nominare l'enum qualcosa come EmployeeNames, e poi, quando scrivo "EmployeeNames" seguito da un ".", Sarebbe bello se si visualizzasse una lista che mostra quali sono le opzioni enum.

+0

Potresti anche essere interessato a: http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions –

risposta

22

In C (e quindi nell'obiettivo C), un tipo di enum deve essere preceduto da enum ogni volta che lo si utilizza.

enum MyEnum enumVar; 

Facendo un typedef:

typedef MyEnum MyEnumT; 

È possibile scrivere il più breve:

MyEnumT enumVar; 

Le dichiarazioni alternativi dichiarano enum stesso e la typedef in una dichiarazione.

// gives the enum itself a name, as well as the typedef 
typedef enum Ename { Bob, Mary, John} EmployeeName; 

// leaves the enum anonymous, only gives a name to the typedef 
typedef enum {Bob, Mary, John} EmployeeName; 

// leaves both anonymous, so Bob, Mary and John are just names for values of an anonymous type 
typedef enum {Bob, Mary, John}; 
+0

Queste sono tutte risposte utili. Questa idea di dichiarare una variabile del tipo enumerato è intrigante. Farlo, suppongo, limita i possibili valori della variabile.Non ho mai usato un enume simile in altre lingue. Ho appena usato la dichiarazione enum come titolare di possibili valori. Ad esempio: Se MyFish = FishSpecies.Mackeral Poi ... o, mentre scrivo, posso ottenere IntelliSense come segue: x = FishSpecies.Cod Hallibut Mackeral ecc (Spiacente non posso formattare questo un commento.) Xcode può fare quel tipo di IntelliSense con un enum, come VB? –

+0

@Scott - il problema è che in C i nomi dei valori di enum possibili vengono uniti nello scope globale (o in C++, entrano nello stesso spazio dei nomi in cui è dichiarato il tipo enum). Quindi in effetti "FishSpecies" non contiene nulla chiamato "Cod". Devi solo dire "Merluzzo". In C++ è buona prassi dichiarare sempre enumerazioni annidate in qualche classe o spazio dei nomi per evitare l'inquinamento del namespace globale. In C++ 1x ci sarà una varietà enum migliorata in cui scrivere 'FishSpecies :: Cod'. E, naturalmente, in C#, VB.NET (e Java 5 o versioni successive penso) ottieni già ciò che ti è familiare. –

+0

Sono abbastanza sicuro che l'Objective C rimanga fedele alla semplice ANSI C a parte le estensioni OO dinamiche che sono molto segregate dal resto della lingua. Approccio totalmente diverso da C++ che mira anche ad essere "una C migliore". Anche se il vantaggio è che puoi combinare le due lingue e ottenere Objective C++ (che è quello che userei se mi dilettavo in iPhone dev, dato che non c'è GC su iPhone, e C++ abilita una soluzione essenziale chiamata puntatori intelligenti ... guardate su!) –

0

Il tuo terzo esempio è lo stesso del vostro ultimo esempio - la typedef non è inutile - GCC dà anche un avvertimento su questo caso:

warning: useless storage class specifier in empty declaration 

Il tuo primo e secondo esempio sono anche in parte equivalente, in quanto entrambi danno il tipo enum al nome EmployeeName. Il primo esempio consente inoltre di utilizzare enum Ename in modo intercambiabile con EmployeeName; nel secondo esempio, EmployeeName è l'unica opzione. Il secondo esempio deve essere scritto come si deve - è possibile scomporre il primo esempio nel modo seguente:

enum Ename { Bob, Mary, John }; 
typedef enum Ename EmployeeName; 

Forse questo aiuta a chiarire le cose?

4

I nomi all'interno di enum { } definiscono i valori enumerati. Quando si assegna un nome, è possibile utilizzarlo come tipo insieme alla parola chiave enum, ad es. enum EmployeeName b = Bob;. Se anche tu hai typedef, puoi eliminare lo enum quando dichiari le variabili di quel tipo, ad es. EmployeeName b = Bob; invece dell'esempio precedente.