2010-04-02 31 views
15

Trong mã mẫu, tôi đã thấy điều này:Mục tiêu C - khi nào nên "gõ" trước "enum", và khi nào nên đặt tên cho enum?

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

và điều này:

typedef enum {Bob, Mary, John} EmployeeName; 

và điều này:

typedef enum {Bob, Mary, John}; 

nhưng những gì thu thập thành công đối với tôi là thế này:

enum {Bob, Mary, John}; 

Tôi đặt dòng đó vào một tệp .h phía trên dòng @interface, và sau đó khi tôi #import tệp .h đó vào tệp .m của một lớp khác, các phương thức có thể thấy enum.

Vì vậy, khi nào các biến thể khác cần thiết?

Nếu tôi có thể đặt tên cho enum một cái gì đó giống như EmployeeNames, và sau đó, khi tôi nhập "EmployeeNames" theo sau là ".", Nó sẽ là tốt đẹp nếu một danh sách bật lên cho thấy những lựa chọn enum là gì.

+0

Bạn cũng có thể quan tâm: http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions –

Trả lời

22

Trong C (và do đó Mục tiêu C), một loại enum phải được bắt đầu bằng enum mỗi khi bạn sử dụng.

enum MyEnum enumVar; 

Bằng cách thực hiện một typedef:

typedef MyEnum MyEnumT; 

Bạn có thể viết ngắn hơn:

MyEnumT enumVar; 

Các tờ khai thay thế khai báo enum chính nó và typedef trong một tuyên bố.

// 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

Đây là tất cả các câu trả lời hữu ích. Ý tưởng này tuyên bố một biến của kiểu liệt kê là hấp dẫn. Làm như vậy, tôi giả sử, giới hạn các giá trị có thể có của biến.Tôi chưa bao giờ sử dụng một enum như thế bằng các ngôn ngữ khác. Tôi chỉ sử dụng khai báo enum như một người giữ các giá trị có thể. Ví dụ: Nếu MyFish = FishSpecies.Mackeral Rồi ... hoặc, như tôi đã gõ, tôi có thể nhận được IntelliSense như sau: x = FishSpecies.Cod Hallibut Mackeral vv (Xin lỗi tôi không thể định dạng này trong một bình luận.) Xcode có thể thực hiện loại IntelliSense đó bằng enum, như VB không? –

+0

@Scott - vấn đề là trong C các tên giá trị enum có thể được sáp nhập vào phạm vi toàn cầu (hoặc trong C++, chúng đi vào cùng một không gian tên kiểu enum được khai báo trong). Vì vậy, trên thực tế 'FishSpecies' không chứa bất cứ thứ gì gọi là 'Cod'. Bạn chỉ cần nói 'Cod'. Trong C++, thực hành tốt của nó luôn luôn khai báo các enums lồng nhau trong một số lớp hoặc không gian tên để tránh ô nhiễm không gian tên chung. Trong C++ 1x sẽ có một loại enum nâng cao mà bạn muốn viết 'FishSpecies :: Cod'. Và tất nhiên trong C#, VB.NET (và Java 5 hoặc sau này tôi nghĩ) bạn đã có được những gì bạn đã quen thuộc. –

+0

Tôi khá chắc chắn Mục tiêu C vẫn trung thành với ANSI C đơn giản ngoài các phần mở rộng OO động được tách biệt nhiều với phần còn lại của ngôn ngữ. Cách tiếp cận hoàn toàn khác với C++ nhằm mục đích trở thành "C tốt hơn". Mặc dù lợi thế là bạn có thể kết hợp hai ngôn ngữ và nhận Objective C++ (đó là những gì tôi muốn sử dụng nếu tôi dabbled trong iPhone dev, như không có GC trên iPhone, và C + + cho phép một workaround cần thiết được gọi là thông minh con trỏ ... xem chúng lên!) –

0

Ví dụ thứ ba của bạn cũng giống như ví dụ cuối cùng của bạn - typedef có là vô ích - GCC thậm chí đưa ra một cảnh báo về trường hợp đó:

warning: useless storage class specifier in empty declaration 

ví dụ đầu tiên và thứ hai của bạn cũng là một phần tương đương, trong đó cả hai đều cung cấp cho loại enum một tên EmployeeName. Ví dụ đầu tiên cũng cho phép bạn sử dụng enum Ename thay thế lẫn nhau với EmployeeName; trong ví dụ thứ hai, EmployeeName là tùy chọn duy nhất. Ví dụ thứ hai phải được viết như bạn có - bạn có thể phân tích ví dụ đầu tiên như sau:

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

Có lẽ điều đó sẽ giúp mọi thứ rõ ràng?

4

Tên bên trong enum { } xác định các giá trị được liệt kê. Khi bạn đặt tên cho nó, bạn có thể sử dụng tên này làm loại cùng với từ khóa enum, ví dụ: enum EmployeeName b = Bob;. Nếu bạn cũng typedef, thì bạn có thể thả số enum khi bạn khai báo các biến thuộc loại đó, ví dụ: EmployeeName b = Bob; thay vì ví dụ trước.

Các vấn đề liên quan