2011-06-27 63 views
2

這是一個小程序:從哪裏呢編譯器開始閱讀

#include <iostream> 
using namespace std; 

int main() { 
    f(); 
    system("pause"); 
} 

void f() { 
    static int x = 20 ; 
    class tester { 
    public : 
     tester() { 
      cout << x ; 
     } 
    } x1; 
} 

,我來到這裏的錯誤是:錯誤C3861:「F」:未找到

如果我把標識主要功能f我會得到所需的輸出。

爲什麼是這樣? 我被告知程序執行開始於main。根據這個代碼也應該在第一種情況下運行。

編譯器如何開始讀取程序?

+2

從上到下,你的f()在最下面,當然它看不到它 – Kobe

+0

@vBx你說像所有的語言都需要定義之前的引用。用Python寫這個,看看會發生什麼 –

回答

6

編譯的開始和執行的開頭該計劃是兩件不同的事情。

執行從main開始。

編譯從文件開頭開始;編譯器不會「跳過」文件以找到所需的部分,但它會以線性方式讀取輸入(我懷疑這與C++語法真的很複雜這一事實有關)。

當編譯器在解析文件的某個時刻,它只知道到目前爲止已經聲明/定義了什麼。。

正因爲如此,函數原型(和非限定的一般聲明)已經發明:的定義的文件中在文件的開頭提出的所有函數的原型,通常後#include指令或分開的包含文件中。原型告訴編譯器,這些函數將在稍後定義,函數簽名是什麼(即名稱,參數,返回值)。

該原型是作爲一個正常的功能,但沒有身體,它被分號代替。例如,在您的代碼中,您可以編寫

void f(); 

之前的main


  1. IIRC有一些放寬這一規則,讓編譯器「等待」一些聲明,使一些模板魔術的工作,但在這裏,這是不相關的。

  2. 在原型中也常見的是不寫出參數的名稱,只留下它們的類型(這也可以在函數定義中完成,但除非你有一個正式的參數不要使用)。不過,我更願意將參數名稱作爲文檔的一種形式。

+0

你的觀點2有點誤導;在函數定義中,您同樣可以省略參數的名稱。顯然,你不能引用未命名的參數,因此不能使用它的值。 – MSalters

+0

@ MSalters:不知道,我會解決答案。 –

2

不,編譯器在使用前至少需要看到f()的聲明。 c(++)代碼文件是一個簡單的文本文件,必須由編譯器從頭到尾讀取。

7

我被告知程序執行從main開始。

而這正是這一點。

編譯器從main開始,然後看到到目前爲止還沒有遇到的f()的調用(因爲它之後定義),所以它不知道如何處理它。

如果要定義fmain後,你可以將之前的函數原型,如

#include <iostream> 
using namespace std; 

void f(); // <--- This tells the compiler that a function name f will be defined 

int main() { 
f(); 
system("pause"); 
} 

void f() { 
static int x = 20 ; 
class tester { 
public : 
    tester() { 
     cout << x ; 
    } 
} x1; 
} 
+0

ok ..我有點困惑 –

3

爲了能夠調用它必須聲明的函數在代碼中的一些早期的點。這只是旨在幫助編譯器的語言規則。

您可以聲明函數較早與例如,

void f(); 

...然後後主要定義它爲你做了。

3

編譯器從頂部開始讀取到底部。

你需要有類似:

#include <iostream> 
using namespace std; 

void f(); 

int main() { 
f(); 
system("pause"); 
} 

void f() { 
static int x = 20 ; 
class tester { 
public : 
    tester() { 
     cout << x ; 
    } 
} x1; 
} 
2

在編譯過程中,當編譯器正在評估main()它需要知道什麼是f()事先能夠產生正確的彙編代碼調用這個函數。這就是爲什麼在這種情況下你需要把它放在main()之前。

作爲替代你可以聲明的f()main()之前,所以編譯器知道它的原型是宣告別的地方在你的文件的本地函數:

void f(); // prototype 

int main() 
{ 
    // .. code .. 
} 

void f() // implementation of f() 
{ 
// .. code .. 
}