繁体   English   中英

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

[英]Why does a function need to be declared before it's defined or used?

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

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

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM