Sự khác biệt là cách tiếp cận thứ hai tuyên bố loại có tên là enum SomeEnum
và cũng khai báo tên typedef-SomeEnum
- bí danh cho loại đó. Nó thực sự có thể được kết hợp thành tương đương với một lót
typedef enum SomeEnum { first, second, third } SomeEnum;
mà làm cho nó khá rõ ràng rằng sự khác biệt duy nhất giữa hai phương pháp là liệu có một tên sau từ khóa enum
. Với cách tiếp cận thứ hai, bạn có thể khai báo đối tượng của kiểu enum đó bằng cách sử dụng SomeEnum e
hoặc enum SomeEnum e
, tùy theo bạn thích.
Cách tiếp cận đầu tiên chỉ khai báo typedef-name SomeEnum
cho loại enum ẩn danh ban đầu, có nghĩa là bạn bị giới hạn ở SomeEnum e
khai báo.
Vì vậy, miễn là bạn chỉ sử dụng typedef-name SomeEnum
trong các khai báo của bạn, sẽ không có sự khác biệt giữa hai loại. Tuy nhiên, trong một số trường hợp, bạn có thể phải sử dụng tên đầy đủ của loại enum SomeEnum
. Trong cách tiếp cận đầu tiên mà tên không có sẵn, vì vậy bạn sẽ không may mắn.
Ví dụ, nếu sau khi tuyên bố ở trên, bạn cũng khai báo một biến có tên SomeEnum
trong một số phạm vi lồng nhau
int SomeEnum;
tên của biến sẽ ẩn typedef tên của enum, do đó làm cho tuyên bố này bất hợp pháp
SomeEnum e; /* ERROR: `SomeEnum` is not a type */
Tuy nhiên, nếu bạn sử dụng cách tiếp cận thứ hai khi tuyên bố enum, bạn có thể làm việc xung quanh vấn đề này bằng cách sử dụng các loại tên đầy đủ
enum SomeEnum e; /* OK */
Điều này sẽ không thể thực hiện được nếu bạn đã sử dụng cách tiếp cận đầu tiên khi khai báo loại enum của bạn.
Khi sử dụng với cấu trúc, tên sau khi struct
là điều bắt buộc khi bạn cần một loại tự tham khảo (một loại có chứa một con trỏ đến cùng loại), như
typedef struct SomeStruct {
struct SomeStruct *next;
} SomeStruct;
Cuối cùng, trong cách tiếp cận thứ hai tên typedef là hoàn toàn tùy chọn. Bạn chỉ có thể khai báo
enum SomeEnum { first, second, third };
và chỉ sử dụng enum SomeEnum
mỗi khi bạn cần tham khảo loại này.