Function 对函数声明和原型感到困惑

Function 对函数声明和原型感到困惑,function,call,declaration,Function,Call,Declaration,我有一个简单的问题,但它困扰着我。我的在线教科书说这是真的-->“函数声明在函数定义之前启用对函数的调用。”我认为这是错误的,因为如果函数仅在声明之后才被调用,程序如何知道它做了什么。我想这会导致编译时错误。有人能解释为什么这是真的吗?谢谢。这意味着,一旦声明了函数,编译器就会知道它的存在 因此,您可以编写调用该函数的代码,编译器不会抱怨。这可能就是为什么教科书中说在函数定义之前启用对函数的调用 当然,您必须在某个地方定义函数(写入函数体),程序才能正确执行 文本并不意味着声明就足以让它工作,它

我有一个简单的问题,但它困扰着我。我的在线教科书说这是真的-->“函数声明在函数定义之前启用对函数的调用。”我认为这是错误的,因为如果函数仅在声明之后才被调用,程序如何知道它做了什么。我想这会导致编译时错误。有人能解释为什么这是真的吗?谢谢。

这意味着,一旦声明了函数,编译器就会知道它的存在

因此,您可以编写调用该函数的代码,编译器不会抱怨。这可能就是为什么教科书中说在函数定义之前启用对函数的调用

当然,您必须在某个地方定义函数(写入函数体),程序才能正确执行


文本并不意味着声明就足以让它工作,它只说明声明函数允许编写调用它的代码,而无需定义到位。

某些语言的编译器需要知道函数在代码中首次引用时的签名

如果没有原型,程序员必须先编写函数的定义,然后才能引用它。这将使两个函数不可能相互调用


原型为编译器提供函数的签名,该签名将在以后的代码中编写(定义),或者可能在不同的代码文件中编写。

当给出声明时,该函数就可以被代码用于编译。以后可以验证和编译函数的定义

在运行时,函数的调用方(基于声明)链接到定义

Java示例

在Java中,接口中的方法可视为声明:

public interface IHelloWorld {

    void sayHello();

}
public abstract class AbstractHelloWorld {

    public void sayHello(String name);

}
以及一个实现该方法的类(在接口中声明),作为定义:

public class HelloWorld implements IHelloWorld {

    @Override
    public void sayHello(String name) {
        System.out.println("Hello " + name);
    }

}
当另一个类在接口中使用该方法时,它有足够的格式来完成编译。在运行时,它需要获取实现接口的具体类的实例


这同样适用于包含方法声明的抽象类:

public interface IHelloWorld {

    void sayHello();

}
public abstract class AbstractHelloWorld {

    public void sayHello(String name);

}
混凝土类将如下所示:

public class HelloWorld extends AbstractHelloWorld {

    @Override
    public void sayHello(String name) {
        System.out.println("Hello " + name);
    }

}

你的书描述了我们所谓的远期声明

前向声明是程序员尚未给出完整定义的标识符(表示类型、变量、常量或函数等实体)的声明

来源

如果你做了一个函数声明,这意味着你告诉编译器你的函数是什么样子的(函数签名),这样你就可以在你的代码中调用它,但是编译器还不知道这个函数到底做了什么

C中的示例

// I promise you (the compiler) that a class called MyClass exists
@class MyClass;
@interface MyInterface : NSObject {
    MyClass *evenThoughItDoesNotExistYet;
}
@end
h函数定义

hello.m-函数声明

这就是为什么如果要调用其中的函数,就必须包含.h文件的原因

目标C中的示例

// I promise you (the compiler) that a class called MyClass exists
@class MyClass;
@interface MyInterface : NSObject {
    MyClass *evenThoughItDoesNotExistYet;
}
@end
“隐式”转发声明


其他一些语言,比如ruby,在内部执行这个转发声明。为了实现这一点,他们对代码进行多次扫描,列出所有函数,然后验证代码中调用的所有函数是否都存在。

是否涉及特定语言?接口/实现示例有误导性。@basgys您能解释为什么会有误导性吗?您的解释和示例是两码事。OO中接口的概念与函数的声明和实现无关。@basguys,在Java中,这是展示这个概念的唯一方式。As方法只能在接口或类的上下文中声明。其他语言可能确实会更清晰地显示这个概念。