我有一个简单的问题,但它让我烦恼。我的在线教科书说这是真的 - > "函数声明允许在函数定义之前调用函数。"我认为这是错误的,因为如果一个函数只在声明之后被调用,程序如何知道它的作用。我认为它会导致编译时错误。有人可以解释为什么这是真的吗?感谢。
答案 0 :(得分:2)
这意味着一旦你声明该函数,编译器就会知道它的存在。
因此,您可以编写调用该函数的代码,编译器不会抱怨。这可能就是为什么你的教科书说能够在函数定义之前调用函数。
当然,您必须在某处定义函数(编写函数体)才能使程序正确执行。
该文本并不意味着该声明足以使其工作,它只表示声明该函数允许编写调用它的代码而尚未定义该定义。
答案 1 :(得分:2)
你的书描述了我们所谓的前瞻性宣言。
前向声明是程序员尚未给出完整定义的标识符(表示类型,变量,常量或函数等实体)的声明。
如果你接受一个函数声明,这意味着你告诉编译器你的函数是什么样的(函数签名),这样你就可以在你的代码中调用它,但是编译器还不知道这个函数实际上做了什么。
C中的示例
hello.h - 功能定义
void helloWorld();
hello.m - 功能声明
void helloWorld() {
printf("Hello World");
}
如果你想调用那里的函数,你就必须包含.h文件。
目标C中的示例
// I promise you (the compiler) that a class called MyClass exists
@class MyClass;
@interface MyInterface : NSObject {
MyClass *evenThoughItDoesNotExistYet;
}
@end
<强>&#34;隐&#34;前瞻性声明
像ruby这样的其他一些语言在内部执行此前向声明。为实现这一目标,他们多次扫描代码以列出所有函数,然后验证代码中调用的所有函数是否存在。
答案 2 :(得分:1)
某些语言的某些编译器在代码中首次引用时需要知道函数的签名。
如果没有原型,程序员必须先编写函数的定义才能引用它。这将使两个函数不可能相互调用。
原型为编译器提供了函数的签名,该函数将在代码中稍后编写(定义),或者可能在不同的代码文件中。
答案 3 :(得分:0)
当给出声明时,该函数已经可以通过代码用于编译。之后,可以验证和编译函数的定义。
在运行时,函数的调用者(基于声明)链接到定义。
Java中的示例
在Java中,接口中的方法可以看作是声明:
public interface IHelloWorld {
void sayHello();
}
实现该方法的类,在接口中声明为定义:
public class HelloWorld implements IHelloWorld {
@Override
public void sayHello(String name) {
System.out.println("Hello " + name);
}
}
当另一个类在接口中使用该方法时,它有足够的niformation来完成编译。在运行时,它需要获取一个具体类的实例,它实现了接口。
同样适用于抽象类,它包含方法声明:
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);
}
}