声明一个结构:typedef struct name name;

Declaring a structure: typedef struct name name;

我们都知道如何在 C:

中声明结构
struct Label1{ /* variables */ } Label2; // As I learned

但我想知道为什么这段代码没有声明就可以工作'struct name':

typedef struct name s_name;

或者事实上,输入代码

struct name;

意思是我把'struct name'声明为空结构之类的?

代码示例:

typedef struct Data Data;
struct Data{ /*variables*/ };

如果在第一行中将 struct Data 声明为 void,那么在第二行中就像我用成员重新声明它一样。

这个点的解释是什么?

typedef 将 s_name 声明为结构名称的别名,以便您可以声明变量,例如:

s_name *sptr;

struct name;

声明有一个名为 name 的结构类型,但没有定义其内容。这通常是为了能够将变量声明为结构类型的指针。在定义之前,您不能声明实际结构类型的变量。

类似于:

struct MyStruct;

称为前向引用。它创建了一个不完整的类型,并告诉编译器将有一个具有该名称的类型(它是一个结构 - 它同样适用于联合),以及详细信息 "follow later"。在完成类型之前,您无法定义此类类型的变量。

typedef struct MyStruct MyType;

只会将类型名称定义为该结构。这仍然是一个不完整的类型。

但是,您可以取一个指向不完整类型的指针:

MyType *my_t_pointer;
struct MyStruct *my_s_pointer;

当您提供完整声明时,这对于具有指向相同类型 objects 的指针的结构很有用,"completing" 类型:

struct MyStruct {
    struct MyStruct *next;
};

实际上,这是为列表、树和所有其他递归创建节点的唯一方法 data-structures。这是 C 程序的主要部分(有时是隐藏的)。

此外,此机制用于隐藏实现细节。 header 中的函数只需要知道结构存在 take/pass 指向它的指针。这些函数的使用不需要知道结构的细节(但是这样它不能分配它,所以模块必须覆盖所有需要知道结构细节的方面)。完整的声明只在模块的实现文件中。 这些指针被称为 "opaque",因为不能 "look through",即访问结构的字段,因为它们根本不知道。

my_module.h:

struct MyStruct;

extern void my_init(struct MyStruct *obj);

my_module.c:

struct MyStruct {
    int f1;
    ...
};

my_init(struct MyStruct *obj)
{
    ...
}