这里发生了几件事。首先,正如其他人所说,编译器对未知类型的抱怨可能是因为您需要在使用它们之前定义类型。更重要的是理解三件事的语法:(1) 结构定义,(2) 结构声明,和 (3) typedef。
定义结构时,结构可以是命名的,也可以是未命名的(如果未命名,则必须立即使用它(将在下面进一步解释这意味着什么))。
struct Name {
...
};
这定义了一个名为“struct Name”的类型,然后可以用来声明一个结构变量:
struct Name myNameStruct;
这声明了一个名为的变量myNameStruct
,它是一个 struct 类型struct Name
。
你也可以定义一个结构体,同时声明一个结构体变量:
struct Name {
...
} myNameStruct;
和以前一样,这声明了一个名为的变量myNameStruct
,它是一个类型的结构struct Name
......但它同时定义了类型 struct Name
。
该类型可以再次用于声明另一个变量:
struct Name myOtherNameStruct;
现在 typedef 只是一种为具有特定名称的类型别名的方法:
typedef OldTypeName NewTypeName;
鉴于上述 typedef,任何时候使用NewTypeName
它都与使用OldTypeName
. 在 C 编程语言中,这对结构特别有用,因为它使您能够在声明该类型的变量时省略“结构”一词,并将结构的名称简单地视为一种类型(就像我们在C++)。这是一个先定义结构,然后对结构进行类型定义的示例:
struct Name {
...
};
typedef struct Name Name_t;
在上面 OldTypeName 是struct Name
和 NewTypeName 是Name_t
。所以现在,要声明一个 struct Name 类型的变量,而不是写:
struct Name myNameStruct;
我可以简单地写:
Name_t myNameStruct;
还要注意,typedef 可以与结构定义结合使用,这就是您在代码中所做的:
typedef struct {
...
} Name_t;
这也可以在命名结构时完成,但这是多余的:
typedef struct Name {
...
} Name_t;
注意:在上面的语法中,由于您以“typedef”开头,因此整个语句是一个typedef
语句,其中 OldTypeName 恰好是一个结构定义。因此,编译器将右大括号 }之后的名称解释为 NewTypeName ...它不是变量名称(因为它在没有 typedef 的语法中,在这种情况下,您将定义结构并声明结构变量同时)。
此外,如果您声明 typedef,但在最后省略 Name_t,那么您实际上创建了一个 INCOMPLETE typedef 语句,因为编译器将“ struct Name { ... }
”中的所有内容视为 OldTypeName,并且您没有为 typedef 提供 NewTypeName。这就是为什么编译器对您编写的代码不满意的原因(尽管编译器的消息相当神秘,因为它不太确定您做错了什么)。
现在,正如我上面提到的,如果你在定义它的时候没有命名结构类型,那么你必须立即使用它来声明一个变量:
struct {
...
} myNameStruct; // declares myNameStruct as a variable with this struct
// definition, but the definition cannot be re-used.
或者您可以在 typedef 中使用未命名的结构类型:
typedef struct {
...
} Name_t;
这个最终的语法是您在编写时实际所做的:
typedef struct{
char firstName[56];
char lastName[56];
} Author;
编译器很高兴。HTH。
关于 _t 后缀的评论/问题:
_t 后缀是一种约定,用于向阅读代码的人表明带有 _t 的符号名称是类型名称(而不是变量名称)。编译器不解析,也不知道 _t。
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 相对)。高温高压