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

时间:2010-02-07 19:44:14

标签: c# java c++ c

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

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

5 个答案:

答案 0 :(得分:21)

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

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

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

答案 1 :(得分:8)

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

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

由于以下几个原因,

C无法正常工作:

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

  • C故意绕过类型机制

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

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

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

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:2)

C ++与Java / C# - 单通道编译器(C ++)与多通道编译器(Java& C#)。多次通过允许Java和C#编译器查看未来的类型和函数原型。

C ++与C - 具有默认声明的C功能基本上是一个错误,在C ++中已得到修复。它会导致问题,并且它是gcc的启用警告。在C ++中,参数构成函数导出名称(name-mangling)的一部分,因此必须先知道才能调用正确的函数。

答案 4 :(得分:-3)

  

在C ++中,一个“必须”在使用/定义之前声明一个函数。为什么会这样?需要什么?我们不会在C#或Java中这样做。

我想说,那不是真的。是的,在C ++中,你必须在引用它之前定义一个函数签名(prototype)。但是你可以暂时离开这个实现。

在Java中不起作用:如果没有编译该类(注意:与实现一起)并且在javac类路径中可用,则无法调用某个类的方法。因此,Java在这个意义上更加严格。