2015-10-21 45 views
2

我有一個簡單的問題,但它使我煩惱。我的在線教科書說這是真的 - >「函數聲明在函數定義之前啓用對函數的調用。」我認爲這是錯誤的,因爲如果一個函數只有在聲明後才被調用,那麼程序如何知道它的功能。我想這會導致編譯時錯誤。有人能解釋爲什麼這是真的嗎?謝謝。關於函數聲明和原型的困惑

+2

是否涉及特定語言? – Verhagen

回答

2

這意味着一旦你聲明瞭這個函數,編譯器就會知道它的存在。

因此,您可以編寫代碼,調用該函數和編譯器不會抱怨。這可能就是爲什麼你的教科書上說在函數定義之前啓用了對該函數的調用。

當然,您必須然後定義某處的函數(寫入函數的主體)爲程序正確執行。

該文本並不意味着聲明足以讓它工作,它只是聲明聲明該函數允許編寫調用它的代碼,而沒有定義到位。

+0

我現在看到非常感謝你解釋它。 – Flower

1

某些語言的某些編譯器在代碼中首次引用時需要知道函數的簽名。

如果沒有原型,程序員必須在函數被引用之前編寫函數的定義。這將使兩個功能不可能相互呼叫。

原型爲編譯器提供了函數的簽名,該函數將稍後寫入(定義)在代碼中,或者可能在不同的代碼文件中。

0

當聲明被給出時,那麼函數已經可以被代碼用於編譯。稍後,可以驗證和編譯函數的定義。

在運行時,函數的調用者(基於聲明)鏈接到定義。在Java中

在Java中的接口的方法可被看作是聲明:

和實施的方法中,這是在接口聲明的類,作爲定義:

public class HelloWorld implements IHelloWorld { 

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

} 

當另一個類在接口中使用該方法時,它有足夠的信息來完成彙編。在運行時,它需要獲得一個實現接口的具體類的實例。


這同樣適用於一個抽象類,它包含一個方法聲明:

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); 
    } 

} 
+0

接口/實現示例具有誤導性。 – basgys

+0

@basgys你能解釋它爲什麼會產生誤導嗎? – Verhagen

+0

你的解釋和你的例子是兩回事。 OO中的接口概念與函數聲明和實現無關。 – basgys

2

你的書中描述了我們所說的向前宣言。

前向聲明是程序員尚未給出完整定義的標識符(表示實體,如類型,變量,常量或函數)的聲明。

來源wikipedia

如果你把一個函數聲明,就意味着告訴編譯你的函數將如何看起來像(函數簽名),這樣就可以在你的代碼中調用它,但編譯器還不知道這個函數實際上做了什麼。

用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 

「隱」 向前聲明

一些其他語言,如紅寶石內部做到這一點提前聲明。爲了實現這一點,他們多次掃描代碼以列出所有函數,然後驗證代碼中調用的所有函數是否存在。