複製鏈接
請複製以下鏈接發送給好友

編譯單元

鎖定
當一個c或cpp文件在編譯時,預處理器首先遞歸包含頭文件,形成一個含有所有必要信息的單個源文件,這個源文件就是一個編譯單元。
中文名
編譯單元
外文名
translation unit
適用領域
程序、代碼
相關概念
源文件、預編譯、編譯器

編譯單元C++中的編譯單元

編譯單元,指的是代碼的物理組織形式。根據C++標準,每一個cpp 文件就是一個編譯單元。
  • 編譯器不會去編譯 `.h` 或者 `.hpp` 文件;
  • 編譯器只會編譯 `.c` 或 `.cpp` 文件;
簡單來説,當一個c或cpp文件在編譯時,預處理器首先遞歸包含頭文件,這也就是為什麼常會有:#ifndef……#define……#endif。之後,形成一個含有所有必要信息的單個源文件,這個源文件就是一個編譯單元。這個編譯單元會被編譯成為一個與cpp文件名同名的目標文件 。
編譯器不能檢查跨越目標文件或編譯單元之間的名稱衝突,這是鏈接器的工作。鏈接器把不同編譯單元中產生的符號聯繫起來,構成一個可執行程序。如:
//文件first.cpp  
int integerValue = 0;  
int main(){  
    int integerValue = 0;  
    return 0;  
};  
//文件second.cpp  
int integerValue = 0;  
/* 錯誤: error LNK2005: "int integerValue" (?integerValue@@3HA) 已經在 second.obj 中定義    first.obj   */  

GCC將C++代碼轉為機器碼,理論上需要四個步驟:預處理(preprocessing)、編譯(compilation)、彙編(assembly)以及鏈接(linking)3;四個步驟對應四個主體:預處理器(preprocessor)、編譯器(compiler)、彙編器(assembler)以及鏈接器(linker)。實際預處理與編譯其實是一個步驟,共需要三個步驟:預處理&編譯彙編以及鏈接

編譯單元Java中的編譯單元

當編寫一個Java源代碼文件時,此文件以.java結尾,被稱為編譯單元
1、 編譯單元中可以有一個public類,且只能有一個public類,作為外界訪問該類的接口,該類的名稱必須與文件名稱一樣。
2、 編譯單元中可以沒有public類,但必須有一個類名稱與文件名稱相同。
3、 編譯單元中可以有一些額外的類,這些類在包訪問權限的 [1] 
代碼組織
1、當編譯(javac)一個.java文件時,在該編譯單元(即.java文件)中的每個類都會有一個輸出文件.class文件,每個輸出文件的名稱與.java文件中每個類的名稱相同。
2、Java可運行程序是一組可以打包並壓縮為一個Java文檔文件(JAR文件)的.class文件。Java解釋器負責這些文件的查找、裝載和解釋。
Java解釋器運行過程
1、 找出環境變量CLASSPATH(通過操作系統設置,也可不用設置,一般編譯環境會為你設置),CLASSPATH包含一個或多個目錄,用來查找.class文件的根目錄。
2、 從根目錄開始,解釋器獲取包的名稱並將每個句點替換成\
3、 得到的路徑與CLASSPATH中的各個不同的項相連接,解釋器就在這些目錄中查找與你創建的類名稱相關的.class文件 [2] 

編譯單元在多個編譯單元中如何定義常量(C++)

【方法一】: 在某個公用的頭文件中直接在某個名字空間中或者全局名字空間中定義符號常量並初始化(有無static)無所謂,例如:
// CommonDef.h
const int MAX_LENGTH=1024;
然後每一個使用它的編譯單元#include改頭文件即可
【方法二】: 在某個公用頭文件中並且在某個名字空間中或者全局名字空間中將符號常量聲明為extern的,例如:
//CommonDef.h
extern const int MAX_LENGTH;
並且在某個源文件中定義一次並初始化:
const int MAX_LENGTH=1024;
然後每一個使用它的編譯單元#include上述頭文件即可。
兩種方法的比較
優點
方法一:
維護方便
方法二:
(1)節約存儲,每一個編譯單元訪問都是這個唯一的定義。
(2)修改初值後只需重新編譯定義所在編譯單元即可,影響面很小。
缺點
方法一:
(1)如果修改常量初值,則將影響多個編譯單元,所有受影響的編譯單元必須重新編譯。
(2)每一個符號常量在每一個包含了它們的編譯單元內都存在一份獨立的拷貝內容,每個編譯單元訪問的就是各自的拷貝內容,因此浪費存儲空間。
方法二:
如果要改變初值,要改變源文件 [3] 
參考資料
  • 1.    李靜,孫曉鍾. LISP 編譯系統中無用單元回收的實現機制及其優化[J]. 湖北工學院學報,1997,(04):19-24.
  • 2.    蘆運照,張兆慶. Linux下優化編譯單元的程序調用共享連接技術[J]. 計算機科學,2004,(12):186-188.
  • 3.    王家源. 編譯程序中節省存儲單元的兩個算法[J]. 上海機械學院學報,1987,(02):61-68.