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

Mic*_*erg 8 c struct typedef

我们都知道如何在C中声明一个结构:

struct Label1{ /* variables */ } Label2; // As I learned
Run Code Online (Sandbox Code Playgroud)

但我想知道为什么这段代码在没有声明'struct name'的情况下工作:

typedef struct name s_name;
Run Code Online (Sandbox Code Playgroud)

或者实际上是键入代码

struct name;
Run Code Online (Sandbox Code Playgroud)

是说我将'struct name'声明为void结构或类似的东西?

代码示例:

typedef struct Data Data;
struct Data{ /*variables*/ };
Run Code Online (Sandbox Code Playgroud)

如果在第一行中struct data被声明为void one,那么在第二行中它就像我用成员重新声明它一样.

对于这一点有什么解释?

too*_*ite 9

就像是:

struct MyStruct;
Run Code Online (Sandbox Code Playgroud)

被称为前瞻性参考.它创建了一个不完整的类型,告诉编译器会有一个类型的名称(它是一个结构 - 它同样适用于联合),细节"稍后跟进".在完成类型之前,您无法定义变量.

typedef struct MyStruct MyType;
Run Code Online (Sandbox Code Playgroud)

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

但是,您可以使用指向不完整类型的指针:

MyType *my_t_pointer;
struct MyStruct *my_s_pointer;
Run Code Online (Sandbox Code Playgroud)

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

struct MyStruct {
    struct MyStruct *next;
};
Run Code Online (Sandbox Code Playgroud)

实际上,这是为列表,树和所有其他递归数据结构创建节点的唯一方法.这是C程序的主要部分(有时是隐藏的).

此外,此机制用于隐藏实现细节.标头中的函数只需知道存在的结构来接受/传递指针.使用这些函数不需要知道结构的细节(但是这样它不能分配它,因此模块必须涵盖需要知道结构细节的所有方面).完整声明仅在模块的实现文件中.这些指针被称为"不透明",因为人们不能"透视",即访问结构的字段,因为它们根本不为人所知.

my_module.h:

struct MyStruct;

extern void my_init(struct MyStruct *obj);
Run Code Online (Sandbox Code Playgroud)

my_module.c:

struct MyStruct {
    int f1;
    ...
};

my_init(struct MyStruct *obj)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)