转发声明一种类型 – 这背后的原因是什么

/* Forward declare a type "point" to be a struct. */ typedef struct point point; /* Declare the struct with integer members x, y */ struct point { int x; int y; }; 

你能解释一下前方宣布背后的原因吗?

我注意到没有人真正回答过你问过的问题

向前声明类型的原因是什么?

答案是:C的设计使得它可以通过从上到下读取每个文件来编译。 考虑像C#这样的语言:

 class C { B b; } class B { C c; } 

请注意,如果编译器从上到下,编译器会在知道B是什么之前到达类型B的字段。 实际上,C#编译器从上到下不会读取整个文件。 它会对每个文件进行多次传递,并随着时间的推移建立信息。

现在假设您想编写一个C#编译器,它可以解析上面的程序而不需要多次传递。 不知何故,你必须在遇到字段b之前告诉编译器有一个名为B的类型。 但我们不能只将class B class C移到class C class B之前,因为这会再次产生同样的问题,这次是用C

在我们想象中的一次性C#版本中你可能会说你可以解决这个问题:

 class B; // Tell the compiler that B will be defined later. class C { B b; } class B { C c; } 

你去吧 当编译器到达B b它知道B是稍后定义的类。 B向前宣布

由于C#总是使用多遍方法,因此不需要这个技巧。 但是C的设计者确实需要单通道方法,因此它们需要前向声明的冗余。

这种单程方法旨在使机器具有几K内存并以每秒几千个周期运行的那一天更容易编译; 相比之下,C#的多次扫描方法每次构建复杂的数据结构都很昂贵,并且在速度和内存受限的机器上很难实现。

当然,我们当然拥有数万亿字节内存的机器(记住, 内存磁盘空间 ; RAM只是磁盘上的缓存!)每秒运行数十亿个周期,但我们仍然不得不使用技术来制作编者在20世纪70年代的生活更加轻松。 这就是你使用C时的情况。

 typedef struct point point; struct point { int x; int y; point *next; /* Could be used */ }; 

VS

 // typedef struct point point; struct point { int x; int y; point *next; /* error: unknown type name 'point' */ }; 

什么是typedef?

typedef的目的是从更基本的机器类型中形成复杂类型,并为这种组合分配更简单的名称。 它们最常用于标准声明繁琐,可能令人困惑或可能因实现而异。

所以typedef struct point point; 不是你假设的前瞻性声明。 它将struct point 命名point ,因此无论何时稍后写入point ,它都将引用struct point

那么现在,您可以将变量声明为point p; 而不是struct point p;

这不是一个point的前向声明,这是它的typedef *typedef让你写

 point p; 

代替

 struct point p; 

您的代码中未使用前向声明效果。 但是,使用typedef ,您可以在point结构的声明中开始使用point作为类型名称,而不是struct标记。

实现相同效果的更常见方法是组合定义和typedef ,如下所示:

 typedef struct point { int x; int y; } point; 

* typedef恰好是前向声明类型,但这是一个“副作用”。