C语言 C : typedef 结构名称 {...}; VS typedef struct{...} 名称;
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17720223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C : typedef struct name {...}; VS typedef struct{...} name;
提问by Alek Sobczyk
As title says, i have this code :
正如标题所说,我有这个代码:
typedef struct Book{
int id;
char title[256];
char summary[2048];
int numberOfAuthors;
struct Author *authors;
};
typedef struct Author{
char firstName[56];
char lastName[56];
};
typedef struct Books{
struct Book *arr;
int numberOfBooks;
};
I get these errors from gcc :
我从 gcc 得到这些错误:
bookstore.c:8:2: error: unknown type name ‘Author'
bookstore.c:9:1: warning: useless storage class specifier in empty declaration [enabled by default]
bookstore.c:15:1: warning: useless storage class specifier in empty declaration [enabled by default]
bookstore.c:21:2: error: unknown type name ‘Book'
bookstore.c:23:1: warning: useless storage class specifier in empty declaration [enabled by default]
If i change the typedefs like this :
如果我像这样更改 typedef:
typedef struct{
char firstName[56];
char lastName[56];
} Author;
Then no warnings and no errors occur. Having searched through http://www.amazon.com/C-Programming-Language-2nd-Edition/dp/0131103628and a couple of hours googling i can't figure why the first implementation won't work.
然后没有警告也没有错误发生。通过http://www.amazon.com/C-Programming-Language-2nd-Edition/dp/0131103628搜索并搜索了几个小时后,我无法弄清楚为什么第一个实现不起作用。
回答by Daniel Goldfarb
There are several things going on here. First, as others have said, the compiler's complaint about unknown type may be because you need to define the types before using them. More important though is to understand the syntax of 3 things: (1) struct definition, (2) struct declaration, and (3) typedef.
这里有几件事情正在发生。首先,正如其他人所说,编译器对未知类型的抱怨可能是因为您需要在使用它们之前定义类型。更重要的是理解 3 件事的语法:(1) struct 定义,(2) struct 声明,以及 (3) typedef。
When Defining a struct, the struct can be named, or unnamed (if unnamed, then it must be used immediately (will explain what this means further below)).
在定义结构体时,结构体可以是命名的,也可以是未命名的(如果未命名,则必须立即使用它(将在下面进一步解释这意味着什么))。
struct Name {
...
};
This defines a type called "struct Name" which then can be used to Declare a struct variable:
这定义了一个名为“struct Name”的类型,然后可用于声明结构变量:
struct Name myNameStruct;
This declares a variable called myNameStructwhich is a struct of type struct Name.
这声明了一个名为 的变量myNameStruct,它是一个类型为 的结构体struct Name。
You can also Define a struct, and declare a struct variable at the same time:
也可以定义一个结构体,同时声明一个结构体变量:
struct Name {
...
} myNameStruct;
As before, this declares a variable called myNameStructwhich is a struct of type struct Name... But it does it at the same time it defines the typestruct Name.
The type can be used again to declare another variable:
和以前一样,这声明了一个名为myNameStructstruct 类型的变量struct Name......但它同时定义了 typestruct Name。
该类型可以再次用于声明另一个变量:
struct Name myOtherNameStruct;
Now typedef is just a way to alias a type with a specific name:
现在 typedef 只是一种使用特定名称为类型别名的方法:
typedef OldTypeName NewTypeName;
Given the above typedef, any time you use NewTypeNameit is the same as using OldTypeName. In the C programming language this is particularly useful with structs, because it gives you the ability to leave off the word "struct" when declaring variables of that typeand to treat the struct's name simply as a type on its own (as we do in C++). Here is an example that first Defines the struct, and then typedefs the struct:
鉴于上述 typedef,任何时候使用NewTypeName它都与使用OldTypeName. 在 C 编程语言中,这对结构特别有用,因为它使您能够在声明该类型的变量时省略“结构”一词,并将结构的名称简单地视为一种类型(就像我们在C++)。这是一个首先定义结构,然后对结构进行 typedef 的示例:
struct Name {
...
};
typedef struct Name Name_t;
In the above OldTypeName is struct Nameand NewTypeName is Name_t. So now, to declare a variable of type struct Name, instead of writing:
在上面的 OldTypeNamestruct Name和 NewTypeName 中Name_t。所以现在,要声明一个 struct Name 类型的变量,而不是这样写:
struct Name myNameStruct;
I can simple write:
我可以简单地写:
Name_t myNameStruct;
NOTE ALSO, the typedef CAN BE COMBINED with the struct definition, and this is what you are doing in your code:
还请注意,typedef 可以与结构定义组合,这就是您在代码中所做的:
typedef struct {
...
} Name_t;
This can also be done while naming the struct, but this is superfluous:
这也可以在命名结构时完成,但这是多余的:
typedef struct Name {
...
} Name_t;
NOTE WELL:In the syntax above, since you have started with "typedef" then the whole statement is a typedefstatement, in which the OldTypeName happens to be a struct definition. Therefore the compiler interprets the name coming afterthe right curly brace } as the NewTypeName ... it is NOTthe variable name (as it would be in the syntax without typedef, in which case you would be defining the struct and declaring a struct variable at the same time).
注意:在上面的语法中,由于您以“typedef”开头,因此整个语句是一个typedef语句,其中 OldTypeName 恰好是一个结构定义。因此,编译器将右大括号 }后面的名称解释为 NewTypeName ...它不是变量名称(因为它在没有 typedef 的语法中,在这种情况下,您将定义结构并声明结构变量同时)。
Furthermore, if you state typedef, but leave off the Name_t at then end, then you have effectively created an INCOMPLETE typedef statement, because the compiler considers everything within "struct Name { ... }" as OldTypeName, and you are not providing a NewTypeName for the typedef. This is why the compiler is not happy with the code as you have written it (although the compiler's messages are rather cryptic because it's not quite sure what you did wrong).
此外,如果您声明 typedef,但在结尾处省略 Name_t,那么您已经有效地创建了一个 INCOMPLETE typedef 语句,因为编译器将“ struct Name { ... }”中的所有内容视为 OldTypeName,并且您没有为 typedef 提供 NewTypeName。这就是编译器对您编写的代码不满意的原因(尽管编译器的消息相当神秘,因为它不太确定您做错了什么)。
Now, as I noted above, if you do not name the struct type at the time you define it, then you must use it immediately either to declare a variable:
现在,正如我上面提到的,如果你在定义它时没有命名结构类型,那么你必须立即使用它来声明一个变量:
struct {
...
} myNameStruct; // declares myNameStruct as a variable with this struct
// definition, but the definition cannot be re-used.
Or you can use an unnamed struct type in a typedef:
或者您可以在 typedef 中使用未命名的结构类型:
typedef struct {
...
} Name_t;
This final syntax is what you actually did when you wrote:
最后的语法是您在编写时实际执行的操作:
typedef struct{
char firstName[56];
char lastName[56];
} Author;
And the compiler was happy. HTH.
编译器很高兴。哈。
Regarding the comment/question about the _t suffix:
关于 _t 后缀的评论/问题:
_t suffix is a convention, to indicate to people reading the code that the symbolic name with the _t is a Type name (as opposed to a variable name). The compiler does not parse, nor is it aware of, the _t.
_t 后缀是一种约定,向阅读代码的人表明带有 _t 的符号名称是类型名称(而不是变量名称)。编译器不解析,也不知道 _t。
The C89, and particularly the C99, standard libraries defined many types AND CHOSE TO USE the _t for the names of those types. For example C89 standard defines wchar_t, off_t, ptrdiff_t. The C99 standard defines a lot of extra types, such as uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t, etc. But _t is not reserved, nor specially parsed, nor noticed by the compiler, it is merely a convention that is good to follow when you are defining new types (via typedef) in C. In C++ many people use the convention to start type names with an uppercase, for example, MyNewType ( as opposed to the C convention my_new_type_t ). HTH
C89,尤其是 C99,标准库定义了许多类型并选择使用 _t 作为这些类型的名称。例如 C89 标准定义了 wchar_t、off_t、ptrdiff_t。C99标准定义了很多额外的类型,比如uintptr_t、intmax_t、int8_t、uint_least16_t、uint_fast32_t等。但是_t不是保留的,也不是专门解析的,也不是编译器注意到的,只是一个很好遵循的约定当您在 C 中定义新类型(通过 typedef)时。在 C++ 中,许多人使用约定以大写开头,例如 MyNewType(与 C 约定 my_new_type_t 相反)。HTH
回答by Bechir
The syntax is of typedefis as follow:
语法typedef如下:
typedef old_type new_type
In your first try, you defined the struct Booktype and notBook. In other word, your data type is called struct Bookand not Book.
在您的第一次尝试中,您定义了struct Book类型而不是Book。换句话说,您的数据类型被称为struct Book而不是Book。
In the second form, you used the right syntax of typedef, so the compiler recognizes the type called Book.
在第二种形式中,您使用了正确的 语法typedef,因此编译器可以识别名为 的类型Book。
回答by Andrew Cina
Want to add by clarifying when you actually declare a variable.
想要通过澄清何时实际声明变量来添加。
struct foo {
int a;
} my_foo;
defines fooand immediately declares a variable my_fooof the struct footype, meaning you can use it like this my_foo.a = 5;
定义foo并立即声明my_foo该struct foo类型的变量,这意味着您可以像这样使用它my_foo.a = 5;
However, because typedefsyntax follows typedef <oldname> <newname>
但是,因为typedef语法如下typedef <oldname> <newname>
typedef struct bar {
int b;
} my_bar;
is notdeclaring a variable my_barof type struct bar, my_bar.b = 5;is illegal. It is instead giving a new name to the struct bartype in the form of my_bar. You can now declare the struct bartype with my_barlike this:
是不是声明变量my_bar类型的struct bar,my_bar.b = 5;是非法的。相反,它struct bar以my_bar. 您现在可以像这样声明struct bar类型my_bar:
my_bar some_bar;
回答by aiked0
I think is going to help you understand. http://www.tutorialspoint.com/cprogramming/c_typedef.htm
我想会帮助你理解。 http://www.tutorialspoint.com/cprogramming/c_typedef.htm
bookstore.c:8:2: error: unknown type name ‘Author'
bookstore.c:21:2: error: unknown type name ‘Book'
These are produced because you have to define them before you use them. Move the struct "Author" & "Books" above the struct "Book". This will solve it.
之所以产生这些,是因为您必须在使用它们之前定义它们。将结构体“Author”和“Books”移到结构体“Book”上方。这将解决它。
Also the warning you are getting explains why there is a problem, the compiler identifies "typedef struct Author" as not necessary because you are not properly typedef the struct so there is nothing useful for the compiler to "read".
此外,您收到的警告解释了为什么会出现问题,编译器将“typedef struct Author”标识为没有必要,因为您没有正确 typedef 结构,因此编译器“读取”没有任何用处。
Since you already know the answer should be in this form
既然你已经知道答案应该是这种形式
typedef struct {
...
...
...
} struct-name;
stick with that.
坚持下去。
回答by EoiFirst
You just need to define Author before defining Book.
您只需要在定义 Book 之前定义 Author。
You use Author in Book so it needs to be defined before.
您在 Book 中使用 Author,因此需要先对其进行定义。

