什么是 C 中关于指针的前向引用?
我可以举个例子吗?
请参阅此页面的前向引用。我看不出前向引用与指针和其他 PoD 类型有何不同。
请注意,您可以转发声明类型,并声明指向该类型的变量:
struct MyStruct;
struct MyStruct *ptr;
struct MyStruct var; // ILLEGAL
ptr->member; // ILLEGAL
struct MyStruct {
// ...
};
// Or:
typedef struct MyStruct MyStruct;
MyStruct *ptr;
MyStruct var; // ILLEGAL
ptr->member; // ILLEGAL
struct MyStruct {
// ...
};
我认为这是您在处理指针和前向声明时所要求的。
我认为关于指针的“前向引用”意味着这样的事情:
struct MyStruct *ptr; // this is a forward reference.
struct MyStruct
{
struct MyStruct *next; // another forward reference - this is much more useful
// some data members
};
指针在定义它指向的结构之前声明。
编译器可以解决这个问题,因为指针存储了一个地址,并且您不需要知道该地址是什么来为指针保留内存。
前向引用是当您声明一个类型但不定义它时。
它允许您通过指针(或 C++ 的引用)使用类型,但您不能声明变量。
这是一种告诉编译器存在某些东西的方式
假设您在Plop.h中定义了一个 Plop 结构:
struct Plop
{
int n;
float f;
};
现在您想添加一些适用于该结构的实用程序函数。您创建另一个文件PlopUtils.h(假设您无法更改 Plop.h):
struct Plop; // Instead of including Plop.h, just use a forward declaration to speed up compile time
void doSomething(Plop* plop);
void doNothing(Plop* plop);
现在,当您实现这些功能时,您将需要结构定义,因此您需要在 PlopUtils.cpp 中包含 Plop.h文件:
#include "PlopUtils.h"
#include "Plop.h" // now we need to include the header in order to work with the type
void doSomething(Plop* plop)
{
plop->n ...
}
void doNothing(Plop* plop);
{
plop->f ...
}
我认为 C 编译器最初有一个过程,它可以一起进行符号表构建和语义分析。例如:
....
... foo(a,b) + 1 ... // assumes foo returns int
....
double foo(double x, double y){ ... } // violates earlier assumption
为了防止这种情况,你说:
double foo(double x, double y); // this is the forward declaration
....
... foo(a,b) + 1 ... // correct assumptions made
....
double foo(double x, double y){ ... } // this is the real declaration
帕斯卡也有同样的概念。
添加到以前的答案。强制前向引用的典型情况是 struct foo 包含指向 struct bar 的指针,而 bar 包含指向 foo 的指针(声明之间的循环依赖)。在 C 中表达这种情况的唯一方法是使用前向声明,即:
struct foo;
struct bar
{
struct foo *f;
};
struct foo
{
struct bar *b;
};
前向引用允许 C 编译器执行更少的传递并显着减少编译时间。大约 20 年前,当计算机速度慢得多且编译器效率低下时,这可能很重要。