4

假设你有这个伪代码

do_something();

function do_something(){
   print "I am saying hello.";
}

为什么某些编程语言需要调用 do_something() 出现在函数声明下方才能运行代码?

4

2 回答 2

7

编程语言使用符号表来保存源代码中使用的各种类、函数等。一些语言在一次编译中进行编译,因此符号在使用后立即从符号表中提取出来。其他人使用两遍,其中第一遍用于填充表格,然后第二遍用于查找条目。

于 2010-01-28T05:51:17.300 回答
3

大多数具有静态类型系统的语言都设计为在使用前需要定义,这意味着在调用之前必须有某种函数声明,以便可以检查调用(例如,函数是否获得了正确的数量和类型论据)。这种设计有助于阅读程序的人和编译器:你看到的一切都已经被定义了。易于阅读和一次性编译器的流行可以解释这种设计规则的流行。

不幸的是,使用前的定义不能很好地与相互递归配合使用,因此语言设计者采用了一种丑陋的黑客手段

  1. 声明(有时称为 Pascal 中关键字的“前向声明”)
  2. 利用
  3. 定义

您在 C 中的类型级别以“不完整struct声明”的形式看到相同的现象。

大约在 1990 年,一些语言设计者发现没有抽象语法树的一次性编译器应该成为过去,那个时代的两个非常好的设计——Modula -3Haskell在使用前就摆脱了定义:在那些在语言中,任何定义的函数或变量在其范围内都是可见的,包括定义之前的程序部分。换句话说,相互递归是类型和函数的默认设置。很好,我说——这些语言没有丑陋和不必要的前向声明。

为什么[使用前有定义]?

  • 1975 年轻松编写一次性编译器。

  • 在使用前没有定义,你必须更加努力地考虑相互递归,尤其是相互递归的类型定义。

  • 有些人认为它使人们更容易阅读代码。

于 2010-02-01T03:13:20.480 回答