Có một số điều đang diễn ra tại đây. Thứ nhất, như những người khác đã nói, khiếu nại của trình biên dịch về loại không xác định có thể là do bạn cần xác định các loại trước khi sử dụng chúng. Quan trọng hơn mặc dù là hiểu cú pháp của 3 điều: (1) struct definition, (2) struct declaration, và (3) typedef.
Khi xác định cấu trúc, cấu trúc có thể được đặt tên hoặc chưa đặt tên (nếu chưa đặt tên, thì phải được sử dụng ngay lập tức (sẽ giải thích ý nghĩa của điều này bên dưới)).
struct Name {
...
};
này định nghĩa một loại gọi là "struct Name" mà sau đó có thể được sử dụng để Khai báo một biến struct:
struct Name myNameStruct;
này khai báo một biến gọi là myNameStruct
mà là một struct loại struct Name
.
Bạn cũng có thể Xác định một cấu trúc, và khai báo một biến struct cùng một lúc:
struct Name {
...
} myNameStruct;
Như trước đây, điều này khai báo một biến gọi là myNameStruct
mà là một struct loại struct Name
... Nhưng nó hiện nó cùng lúc khai báo loạistruct Name
.
Loại có thể được sử dụng một lần nữa tuyên bố một biến khác:
struct Name myOtherNameStruct;
Bây giờ typedef chỉ là một cách để bí danh một kiểu với một tên cụ thể:
typedef OldTypeName NewTypeName;
Với typedef trên, bất cứ lúc nào bạn sử dụng NewTypeName
cũng giống như sử dụng OldTypeName
. Trong ngôn ngữ lập trình C, điều này đặc biệt hữu ích với cấu trúc, vì nó cho bạn khả năng loại bỏ từ "struct" khi khai báo các biến kiểu đó và để xử lý tên cấu trúc đơn giản như một kiểu riêng của nó (như chúng ta làm trong C++). Dưới đây là một ví dụ mà đầu tiên Xác định cấu trúc, và sau đó Typedefs struct:
struct Name {
...
};
typedef struct Name Name_t;
Ở phía trên OldTypeName là struct Name
và NewTypeName là Name_t
. Vì vậy, bây giờ, để khai báo một biến kiểu Tên struct, thay vì viết:
struct Name myNameStruct;
tôi có thể đơn giản viết:
Name_t myNameStruct;
LƯU Ý CŨNG, typedef có thể kết hợp với các định nghĩa struct, và đây là những gì bạn đang làm trong mã của bạn:
typedef struct {
...
} Name_t;
này cũng có thể được thực hiện trong khi đặt tên cho các cấu trúc, nhưng điều này là không cần thiết:
typedef struct Name {
...
} Name_t;
LƯU Ý CŨNG: Trong cú pháp trên, kể từ khi bạn đã bắt đầu với "typedef", sau đó toàn bộ tuyên bố là một tuyên bố typedef
, trong đó OldTypeName sẽ xảy ra là một định nghĩa struct. Do đó trình biên dịch diễn giải tên đến sau dấu ngoặc nhọn bên phải} làm NewTypeName ... nó là NOT tên biến (vì nó sẽ nằm trong cú pháp không có typedef, trong trường hợp này bạn sẽ xác định cấu trúc và khai báo một biến struct cùng một lúc).
Hơn nữa, nếu bạn nêu typedef, nhưng để lại ngoài khơi Name_t tại Bấy giờ sự cuối, sau đó bạn đã có hiệu quả tạo ra một tuyên bố typedef INCOMPLETE, bởi vì trình biên dịch xem xét tất cả mọi thứ trong phạm vi "struct Name { ... }
" như OldTypeName, và bạn không cung cấp một NewTypeName cho typedef. Đây là lý do tại sao trình biên dịch không hài lòng với mã như bạn đã viết nó (mặc dù các thông điệp của trình biên dịch khá khó hiểu vì nó không hoàn toàn chắc chắn những gì bạn đã làm sai).
Bây giờ, như tôi đã nói ở trên, nếu bạn không đặt tên cho loại struct tại thời điểm bạn định nghĩa nó, sau đó bạn phải sử dụng nó ngay lập tức hoặc để khai báo một biến:
struct {
...
} myNameStruct; // declares myNameStruct as a variable with this struct
// definition, but the definition cannot be re-used.
Hoặc bạn có thể sử dụng một giấu tên kiểu struct trong một typedef:
typedef struct {
...
} Name_t;
cú pháp cuối cùng này là những gì bạn thực sự đã làm khi bạn đã viết:
typedef struct{
char firstName[56];
char lastName[56];
} Author;
Và trình biên dịch đã được hạnh phúc. HTH.
Về những nhận xét/câu hỏi về các hậu tố _T:
_T hậu tố là một quy ước, để chỉ cho người đọc mã mà tên mang tính biểu tượng với _T là một tên Loại (như trái ngược với một tên biến) . Trình biên dịch không phân tích cú pháp, cũng không nhận thức được, của _t.
C89 và đặc biệt là C99, thư viện chuẩn được xác định nhiều loại VÀ CHỌN SỬ DỤNG _t cho tên của các loại đó. Ví dụ C89 tiêu chuẩn định nghĩa wchar_t, off_t, ptrdiff_t. C99 tiêu chuẩn xác định rất nhiều loại bổ sung, chẳng hạn như uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t, v.v. Nhưng _t không được dành riêng, cũng không được phân tích cú pháp, cũng không nhận thấy bởi trình biên dịch, nó chỉ là một quy ước tốt khi bạn định nghĩa các kiểu mới (thông qua typedef) trong C. Trong C++, nhiều người sử dụng quy ước để bắt đầu nhập tên bằng chữ hoa, ví dụ MyNewType (trái với quy ước C my_new_type_t). HTH
di chuyển 'Tác giả' trước 'Sách'. Cũng lưu ý rằng 'typedef' của bạn là dư thừa – SomeWittyUsername
Làm thế nào có thể thay đổi cấu trúc 'Author' đang loại bỏ' error: tên kiểu không xác định 'Book'' cũng vậy? Xin vui lòng có một cái nhìn [ở đây] (http://msdn.microsoft.com/en-us/library/4x7sfztk%28v=vs.80%29.aspx) mà rõ ràng đề cập đến sự khác biệt giữa typdef một cấu trúc và chỉ xác định một cấu trúc. –