为什么函数需要在定义或使用之前声明?

nor*_*ris 8 c c# c++ java

在C中它是可选的.在C++中,一个"MUST"在使用/定义之前声明一个函数.为什么会这样?需要什么?我们不会在C#或Java中这样做.

有趣的是,我们正在定义一个功能.即使在那时,定义本身也有一个声明,我们需要声明.天知道为什么?

Tho*_*que 21

有趣的是你提到这一点,就在本周Eric Lippert写了一篇与你的问题相关的博客文章:

http://blogs.msdn.com/ericlippert/archive/2010/02/04/how-many-passes.aspx

基本上,这与编译器的工作方式有关.C#和Java编译器进行了多次传递.如果他们遇到一个尚未知道的方法的调用,那不是错误,因为稍后可能会找到定义,并且调用将在下一次传递时解决.请注意,我的解释过于简单,我建议你阅读Eric Lippert的帖子以获得更完整的答案......


Dig*_*oss 8

Java和C#指定语言和二进制目标文件格式,它们是多遍编译器.

因此,他们可以查看以后的定义或单独编译的定义.

由于以下几个原因,C无法正常工作:

  • 在不使用托管代码的情况下,使用类型信息定义与机器无关的对象格式要困难得多

  • C故意允许绕过类型机制

  • 最初定义时,通常没有足够的内存来运行复杂的编译器,也没有原型可供阅读

  • 使用系统特定的库和搜索路径机制,C程序必须是任意大的.所有这些都妨碍了定义基于对象模块的类型系统

  • C可移植性和互操作基础的一部分是规范的"仅输入语言"性质

  • 直到最近,即使是C的有限一次通过性质对于大型程序来说仍然几乎不可行.像Java或C#这样的东西是不可能的:你可以休假,你make(1)仍然无法完成


Run*_* FS 5

基本上,这取决于您如何为该语言编写编译器.在C++中,决定使一次通过编译成为可能.要做到这一点,你(或者更确切地说是编译器)需要能够首先读取所有类,方法等的声明,然后阅读实现(或者用C++术语来定义).在Java和C#中,编译器首先读取所有代码,生成与读取头文件时C++编译器生成的内容相对应的代码.然后,C#/ Java编译器读取实现(也就是定义).因此,在C++中,要求开发人员编写声明,而在C#中,编译器会多次运行代码,为开发人员执行声明工作.

另外,其他语言曾经要求您按照需要的顺序编写函数(如果函数B使用函数A,则必须首先定义A).大多数这些语言都有结构可以让你解决这个问题.在(Turbo)Pascal中,解决方案在某种程度上与在C++中相同.