C 正向声明类型-这背后的原因是什么
你能解释一下转发声明背后的原因吗?这不是一个C 正向声明类型-这背后的原因是什么,c,C,你能解释一下转发声明背后的原因吗?这不是一个点的转发声明,这是一个typedef。typedef允许您编写 /* 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; }; 而不是 point p; 代码中未使
点的转发声明,这是一个typedef
。typedef
允许您编写
/* 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;
};
而不是
point p;
代码中未使用转发声明效果。但是,当typedef
就位后,您可以开始在点
结构的声明中使用点
作为类型名称,而不是结构
标记
实现相同效果的更常见方法是将定义和typedef
组合起来,如下所示:
struct point p;
class C
{
B b;
}
class B
{
C c;
}
*typedef
恰好正向声明了类型,但这是一个“副作用”
vs
typedef的目的是从更基本的机器上形成复杂的类型
键入并为这些组合指定更简单的名称。他们是最
通常在标准声明很麻烦时使用,可能
容易混淆,或可能因实现而异
Sotypedef结构点代码>不是您假定的转发声明。它将struct point
命名为point
,这样当您稍后编写point
时,它将引用struct point
现在,您可以将变量声明为点p代码>而不是结构点p代码>我注意到没有人真正回答你提出的问题,这是
转发声明类型的原因是什么
答案是:C的设计使它可以通过从上到下读取每个文件一次来编译。考虑C语言这样的语言:
请注意,如果编译器从上到下运行,则编译器在知道B
是什么之前会到达B
类型的字段。事实上,C#编译器不会从上到下一次读取整个文件。它对每个文件进行多次传递,在传递过程中积累信息
现在假设您想编写一个C#编译器,它可以在不进行多次传递的情况下解析上面的程序。不知何故,在遇到字段b
之前,您必须告诉编译器有一个名为b
的类型。但是我们不能把B类
移到C类
之前,因为这会再次产生同样的问题,这次是C类
在我们想象的C#的单程版本中,你可能会说你可以像这样绕过这个问题:
struct point p;
class C
{
B b;
}
class B
{
C c;
}
就这样。当编译器到达bb
时,它知道bb
是一个稍后将定义的类<代码>B
已被转发声明
因为C#一直使用多通道方法,所以它不需要这种技巧。但是C的设计者确实希望采用单通道方法,因此他们需要前向声明的冗余
这种单通道方法的设计目的是使编译在当时更容易,当时机器只有几K内存,每秒运行几千个周期;相比之下,C#每次多次扫描构建复杂数据结构的方法成本高昂,而且在速度和内存受限的机器上很难实现
当然,现在我们的机器拥有数万亿字节的内存(请记住,内存就是磁盘空间;RAM只是磁盘上的缓存!),每秒运行数十亿个周期,但我们仍然不得不使用一些技术,使编译器编写者的生活在20世纪70年代变得更轻松。这就是使用C时的情况。这不是一个转发声明,而是一个typedef。但是它与typedef struct point{}有何不同?在编译过程中,C编译器只知道它已经读入的内容。typedef struct point
告诉编译器有一个名为point
的类型(这就足够了)。@Theolodis,事实上它两者都是。在typedef
中使用struct point
是对struct
类型的正向声明。作为回答,它并不完全正确。两者都是。在typedef
中使用struct point
是对struct
类型的正向声明,作为回答不完全正确。两者都是。在typedef中使用struct point是结构的正向声明type@JensGustedt这正是我在脚注中所说的。你所说的“副作用”是什么意思?重要的是,这是一个转发声明,您只能声明已知类型的typedef
s。从那时起,point*
即使不知道struct
@JensGustedt所说的“副作用”,我的意思是“它也会发生”。如果有人需要向前声明一个struct
标记,他会写struct点
并开始使用struct point*
,而不知道struct
的细节。当他想要“直接”效果时,就会发生这种情况。当有人编写typedef
时,他希望它主要用于typedef
,也就是说,当使用struct point
时,能够删除struct
。在typedef
之后,编译器考虑声明的类型,并允许您使用struct point*
,这是“次要”行为。
class C
{
B b;
}
class B
{
C c;
}
class B; // Tell the compiler that B will be defined later.
class C
{
B b;
}
class B
{
C c;
}