# Lecture 1:Getting Started Hello World! --- 每個 C++ 程序都必須有一個名為 main() 的全域函數,程序首先執行該函數。main() 返回的 int 值(如果有)是程序對“系統”的返回值。如果沒有返回值,系統將收到一個表示成功完成的值。main() 中的非零值表示失敗。 關於 C++ 中的 #include,#include 是巨集(Macro)前置處理器指令(Preprocessor directive),它告訴編譯器(Compiler)這個程式必須使用到 iostream 這個表頭檔(Header file)中的函式(Function)與類別(Class)定義。 using namespace 指令表示使用某個名稱空間(Namespace)下的名稱,例如要在主控台進行輸入輸出,使用到 std 中的 cin 和 cout 。如果不寫入該行的話,就必須使用 std::cout ,來表明使用在 std 下的名稱。在標頭檔(.h file)中,不應該使用 using namespace 聲明,因為可能會為包括此標頭檔的文件引入名稱衝突。 撰寫完一個程式需要將人類撰寫的語言轉成電腦CPU可以處理的語言,程式編譯的過程大致可分為四部分,依序為預處理 (preprocessing) 、編譯 (compiling) 、鏈結 (linking)。 1. 預處理 (preprocessing) 在這個階段編譯器主要的工作是修改以 # 符號開頭的指令代碼,這些指令可能是展開引用的外部檔案、 macro 及 define。 * 刪除所有的 #define 並展開所有 macro * 處理所有的預編譯條件,例如 #ifdef, #include (展開引用文件) * 刪除所有 註解 * 增加 行號以及 文件識別名,讓編譯器在編譯失敗時可以顯示錯誤的行數 2. 編譯 (compiling) 此階段包含 compilation 和 assembly,經過 compiling 後便可以產生目標文件檔 (.o/.obj)。compilation 會將展開後的程式碼轉換成,assembly 則將組合語言轉換成對應的機器語言 3. 鏈結 (linking) 這個步驟是讓編譯器能夠知道代碼中外部函數或是外部變數明確的位址。比方說在檔案 main.cpp 中引用了別的檔案 func.cpp 中的 foo() 函數,必須先知道這個函數到底在哪裡,才可以呼叫它。 鏈結要做的事情,就是把多個不同的文件組合在一起,成為一個完整的整體。 .h file 標頭檔 --- 在撰寫程式時有些資料會有相關性,將相關聯的資料組織在一起,對於資料本身的可用性或者是程式碼的可讀性,都會有所幫助。而通常會使用檔頭檔來定義類別,且檔頭檔案的名稱建議與類別名稱相同;並使用另一個 cpp 檔來實作這個類別。 使用預處理器能幫助程式在執行時安全的 include 多次相同的標頭檔,當預處理器讀到程式呼叫 #include .h file 時會將 .h file 中所有的 code 解壓縮。然而如果在多個程式檔案中呼叫同一個 .h file 會產生名稱被多次定義的情況,此時使用 header guard 就可以處理此問題。 ``` #ifndef HELLO_H #define HELLO_H namespace hello{ class Hello{ public: void helloWorld(); }; } #endif ``` 上面使用到預處理器變數(preprocessor variables),來判斷是否已經定義過 HELLO_H,如果沒有,那就先定義 HELLO_H,然後才 #include 後面的東西。