前向参考与前向声明

时间:2009-03-30 09:29:04

标签: forward-declaration forward-reference

我有点困惑。前向声明和前向引用有什么区别?在我的脑海中,当你声明一个尚未实现的函数时,前向声明是不正确的?您是否需要查看指定的情况,以声明案例“前向引用”或“前向声明”?

3 个答案:

答案 0 :(得分:28)

前向声明是在实现和使用它之前声明方法或变量。前向声明的目的是节省编译时间。

变量的前向声明会导致存储空间被搁置,因此您可以稍后设置该变量的值。

函数的前向声明也称为“函数原型”,它是一个声明语句,它告诉编译器函数的返回类型是什么,函数的名称是什么,以及它的参数类型。 C / C ++和Pascal等语言的编译器在查找表中声明符号(包括函数),并在代码中引用它们时引用它们。这些编译器按顺序读取您的代码,即从上到下,因此如果您不转发声明,编译器会发现它无法在查找表中引用的符号,并且会引发一个它不知道的错误如何回应这个功能。

前向声明是对编译器的一个暗示,您已在其他地方定义(填写了实现)该函数。

例如:

int first(int x); // forward declaration of first

...

int first(int x) {
   if (x == 0) return 1;
   else return 2;
}

但是,你问,为什么我们不让编译器对每个源文件进行两次传递:第一个用于索引内部的所有符号,第二个用于解析引用并查找它们?丹故事说:

  

当C于1972年创建时,计算资源更加稀缺   并且以高昂的价格 - 存储复杂物所需的内存   程序的整个符号表一下子就没有了   大多数系统。固定存储也很昂贵,而且非常慢   虚拟内存或存储符号表部分的想法   磁盘根本就不允许合理的编译   时间框架...当您处理寻求时间的磁带时   以秒为单位测量,读取吞吐量以字节为单位进行测量   第二个(不是千字节或兆字节),这非常有意义。

     

C ++,虽然在大约17年后创建,但被定义为超集   C,因此必须使用相同的机制。

     

当Java在1995年推出时,普通计算机已经足够了   即使对于复杂的项目,持有符号表的内存也是如此   不再是一个沉重的负担。并且Java不是设计的   向后兼容C,所以它不需要采用传统   机制。 C#同样没有受到阻碍。

     

因此,他们的设计师选择转移负担   区分符号声明退出程序员和   再把它放在电脑上,因为它的成本与之成比例   汇编的总工作量很小。

在Java和C#中,标识符自动从源文件中识别,并直接从动态库符号中读取。在这些语言中,出于同样的原因不需要头文件。

前向引用正好相反。它指的是在声明之前使用实体。例如:

int first(int x) {
   if (x == 0) return 1;
   return second(x-1); // forward reference to second
}

int second(int x) {
   if (x == 0) return 0;
   return first(x-1);
}

请注意,“前向引用”有时会用作“前向声明”的同义词,但不常用。

答案 1 :(得分:5)

来自Wikipedia

  

前瞻性声明

     

声明尚未定义的变量或函数。他们的定义可以在以后看到。

     

转发参考

     

与Forward Declaration类似,但首先出现变量或函数,定义也已到位。

答案 2 :(得分:3)

前向声明用于允许单一语言编译(C,Pascal)。

如果在没有前向声明(Java,C#)的情况下允许前向引用,则需要双向编译器。