- 功能:把人類寫的程式碼轉化成機器看得懂、可以執行的碼
- 為何要懂?
- 寫出更高效的代碼 ⇒ 編譯、翻譯時效率更高
- 理解編譯器的限制
- 寫出接近最佳化的語言
- 編譯器 vs 直譯器
編譯步驟
- 從你給定的原始碼中讀取單個詞。
- 詞法分析:把字元一個一個拆開
- 關鍵在把字元結合成我們要的單詞、識別符號、符號等
- 把這些詞按照單詞、數字、符號、運算子進行分類。
- 通過模式匹配從分好類的單詞中找出運算子,明確這些運算子想進行的運算。
- 語法解析:提取由詞法分析器產生的標記,並嘗試判斷它們是否符合特定的模式,然後把這些模式與函式呼叫、變數呼叫、數學運算之類的表示式關聯起來。
- 解析器逐詞地定義程式語言的語法。
- 解析器產生一個運算子的抽象語法樹AST(表示式樹)。
- 遍歷表示式樹中的所有運算子,產生相應的二進位制資料。
- 程式碼產生器接收AST產生程式碼或彙編程式碼
- 彙編器(組合語言的編譯器)把彙編程式碼生成相應的二進位制程式碼(機器碼)⇒ .o 目標檔案
- 生成可執行檔案
- 連結器讀取通用的機器碼,然後使它變為一個可執行檔案
C++編譯器
- .h頭文件
- 不被編譯,負責聲明
- 編譯器在編譯MyClass.cpp的時候,對於MyClass這個類以及Fun()這個成員函數,編譯器必須找到它的聲明,這個函數才能被正確編譯。
- 如果有其他cpp需要使用MyClass這個類的時候,也需要他的聲明
//.h文件
#define DEFAULT_VALUE 0
class MyClass{
public:
void fun();
public:
int value = DEFAULT_VALUE
}
//.cpp文件
#include "MyClass.h"
void MyClass::fun(){
// Do something
return;
}
-
預編譯:編譯器把.h頭文件替換到.cpp源文件相關的位置上
class MyClass{
public:
void fun();
public:
int value = 0
}
void MyClass::fun(){
// Do something
return;
}
-
編譯:編譯.cpp源文件,若成功的話會生成目標文件.o for Linux/.obj for Win
- 輸入命令行命令可以看到.o的內容$objdump -x MyClass.o