淺探C 程式編譯過程

2021-10-04 18:56:49 字數 2180 閱讀 2053

通常說的編譯指由源**生成可執行檔案的過程。c++程式的編譯又可以分為幾個子過程:

預處理(preprocessing):在編譯前的對源**進行文字上的預處理。輸出.i檔案。

編譯(compilation):將源**轉化為彙編**。輸出.s檔案。

彙編(assembly):將彙編**轉化為二進位制檔案。輸出.o檔案。

平時執行的編譯命令:

g++ helloworld.cpp -o helloworld.out
預設執行的步驟是執行所有步驟,生成可執行檔案,並刪除中間檔案。所以很少看到什麼 .i, . s, .o檔案。但是你可以使用引數指定執行到哪一步為止:

g++  -e  test.cpp  -o  test.i    //生成預處理後的.i檔案

g++ -s test.i -o test.s //生成彙編.s檔案

g++ -c test.s -o test.o //生成二進位制.o檔案

g++ test.o -o test.out //生成二進位制.out可執行檔案

編譯和彙編不贅述,說一下預處理和鏈結。

預處理由預處理器執行,根據源**的預處理指令對源程式進行編譯前處理。

預處理指令在由#標識,#必須是該行的第乙個非空字元。預處理指令不屬於c/c++語句,所以不需要加分號。主要的預處理指令有#include,#define,#ifdef/ifndef...#endif

其它指令用的不多,就不一一枚舉了。這裡看乙個例子領會預處理:

#ifndef myheader_h

#define myheader_h

#define pi 3.14

struct circur

;#endif

#include "myheader.h"

#define flag //定義乙個標誌巨集

#define pow(x) ((x) * (x)) //用巨集實現函式功能

int main()

;#ifdef flag //條件編譯

double area;

area = pi * pow(circur.radium);

#endif

return 0;

}

使用命令g++ -e prepro.cpp -o prepro.i可以檢視預處理生成的 prepro.i檔案:

# 1 "prepro.cpp"

# 1 ""

# 1 ""

# 1 "prepro.cpp"

# 1 "myheader.h" 1

struct circur

;# 2 "prepro.cpp" 2

int main()

; double area;

area = 3.14 * ((circur.radium) * (circur.radium));

return 0;

}

那些#開頭的字串是注釋。可以看到,標頭檔案的結構定義被複製過來了,巨集定義也都被替換,條件編譯部分也順利保留下來。

乙個cpp檔案(翻譯單元)生成乙個.o檔案,並不能直接執行,因為它可能引用了其它cpp檔案的變數和函式,或者引用標準庫的函式,這些被引用的.o檔案被稱為庫(library),程式必須與庫放在一起才能正確執行。鏈結器的工作正是檢索庫檔案並把它與程式鏈結。

靜態鏈結是把程式與庫檔案打包在一起,它的優點是執行快,移植性好。明顯缺點是(1)目標程式大;(2)如果兩個程式引用了同乙個庫,那麼它們同時執行時會在記憶體中存在兩個副本,浪費記憶體;(3)庫更新後必須重新鏈結。

動態鏈結(預設)則是在程式執行時才進行鏈結的,需要借助動態鏈結器完成。程式在裝載的時候發現引用了某個動態庫(共享庫),則告訴動態鏈結器,動態鏈結器檢查該庫是否在記憶體中,如果在,直接告訴程式它的位址,只有當庫不在記憶體時才需要載入,這樣,即使多個程式引用了相同的庫,記憶體中只會存在乙個庫副本。

C程式編譯過程

題記 前幾天去華為面試實習生,面試官問了個問題,讓我說出乙個程式的詳細編譯過程,當時磕磕絆絆說了一堆東西,事後自己都不知道當時說了什麼,慚愧。c語言編譯過程 編譯,編譯程式讀取源程式 字元流 對之進行詞法和語法的分析,將高階語言指令轉換為功能等效的彙編 再由匯程式設計序轉換為機器語言,並且按照作業系...

C 程式編譯過程

首先是編譯過程整體簡介 編譯過程主要分為 4個過程 1 編譯預處理 預編譯程式完成的工作,可以說成是對源程式的 替換 工作。經過這個過程,生成乙個沒有巨集定義 沒有條件編譯指令 沒有特殊符號的輸出檔案。2 編譯 優化階段 通過詞法分析 語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中...

C程式編譯過程

gcc編譯c 會有四個階段 預處理 將c 中的標頭檔案和巨集進行處理 彙編 把彙編 轉化成機器指令,並以特定的二進位制格式輸出儲存在 o這樣的目標檔案中 流程圖 參考閱讀 3.c程式分析 gcc e hello.c o hello.i 預處理 gcc s hello.i o hello.s 編譯 g...