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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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