为了在C中声明一个结构体,我一直使用以下代码:
typedef struct Foo Foo;
然后在下方某个位置定义它。
为什么我要两次指定结构体的名称 (Foo
)?
typedef struct Foo Foo;
然后在下方某个位置定义它。
为什么我要两次指定结构体的名称 (Foo
)?
struct Foo
是正在创建新类型别名的类型。最后一个 Foo
是新类型的名称。如果您的结构声明可见,则可以像这样编写类型定义和结构声明组合,以避免重复的 Foo
:
typedef struct {
...
} Foo;
typedef old_type new_type
so for
typedef struct Foo Foo;
struct Foo
是旧类型,Foo
是新类型,因此无论何时您键入 Foo
,它实际上是 struct Foo
的别名。
您不必指定两个名称。您可以像这样介绍一个不完整的结构体类型:
struct Foo;
就是这样。或者一个完整的:
struct Foo { int x; };
这些声明都不会将名称引入作用域,它们只是引入了一个结构体的tag。
如果您引入了一个结构体标签,那么您必须在任何地方使用struct
关键字来引用它,例如:
struct Foo f;
void fun(struct Foo *param);
typedef
的作用是避免在每个地方都需要编写 struct Foo
。类型名称可以不同于标记:
typedef struct Foo_s Foo;
Foo f;
void fun(Foo *param);
C++方言改变了规则;在C++中,struct Foo
引入了Foo
作为类型名称和标签(用于C兼容性)。
你可能会看到typedef struct Foo Foo
的一个原因是代码最初是以C++形式编写的,看起来像这样:
struct Foo; // Originally C++ only header file.
void fun(Foo *param);
然后出现了一个要求,即必须支持C语言,至少在头文件中。在C语言中,Foo
类型没有声明:
typedef struct Foo Foo; // Fix for C.
#ifdef __cplusplus
#define extern_c extern "C" // C compatible linkage for fun
#endif
void fun(Foo *param);
#ifdef __cplusplus
}
#endif
虽然在这方面C++可能看起来更方便,但它的对象系统绝对会惩罚用户,因为会重复相同的标识符,你简直无法想象。
要定义一个基本的类骨架,并且构造函数和析构函数不在类声明中内联,我们必须重复七次名称:
class foo {
public:
foo();
~foo();
};
foo::foo()
{
}
foo::~foo()
{
}
幸好C ++程序员至少被免于在任何地方编写 class foo * fooptr ,对吧?
struct Foo
类型名称。一些代码指南甚至将其作为原则。 - StoryTeller - Unslander Monica