C 程序是如何編譯的(c 程序是如何編譯的呢)
C語言的編譯過程是將C語言源代碼轉(zhuǎn)換為機(jī)器代碼的過程。由于C語言是一種中級語言,因此需要編譯器將其轉(zhuǎn)換為可執(zhí)行代碼,以便在我們的計(jì)算機(jī)上運(yùn)行程序。
C程序在編譯過程中經(jīng)歷以下階段:
- 預(yù)處理
- 編譯
- 匯編
- 鏈接
編譯流程
01 我們?nèi)绾尉幾g和運(yùn)行C程序
我們需要一個編譯器和一個代碼編輯器來編譯和運(yùn)行C程序。下面示例是 gcc 編譯器編寫代碼流程:
Step 1: 創(chuàng)建C源文件
我們首先使用編輯器創(chuàng)建一個C程序,并將文件保存為filename.c
vi filename.c
我們可以編寫一個簡單的 Hello World 程序并將其保存。
#include <stdio.h>int main() { printf("Hello, World!"); return 0;}
Step 2: 使用GCC編譯器進(jìn)行編譯
我們在終端中使用以下命令編譯我們的filename.c源文件
gcc filename.c –o filename
我們可以向GCC編譯器傳遞許多指令以執(zhí)行不同的任務(wù),例如:
- 選項(xiàng)-Wall啟用所有編譯器的警告消息。建議使用此選項(xiàng)以生成更好的代碼。
- 選項(xiàng)-o用于指定輸出文件名。如果我們不使用此選項(xiàng),則會生成一個名為a.out的輸出文件。
Step 3: 執(zhí)行程序
編譯后生成可執(zhí)行文件,我們使用以下命令運(yùn)行生成的可執(zhí)行文件。
./filename
程序?qū)⒈粓?zhí)行,并且輸出將顯示在終端中。
執(zhí)行程序
02 編譯過程內(nèi)幕
C程序的編譯過程包括以下四個步驟:預(yù)處理、編譯、匯編和鏈接。
通過執(zhí)行以下命令,我們獲取當(dāng)前目錄中的所有中間文件以及可執(zhí)行文件。
gcc -Wall -save-temps filename.c –o filename
讓我們一一看看這些中間文件包含什么。
預(yù)處理
在此階段,源代碼由預(yù)處理器處理。預(yù)處理器是在編譯器編譯源代碼之前處理源代碼的程序。預(yù)處理的主要目的是為編譯做準(zhǔn)備。預(yù)處理階段包括以下幾個步驟:
- 刪除注釋
- 宏擴(kuò)展
- 文件包含
- 條件編譯
預(yù)處理的輸出存儲在 filename.i 中。
- 代碼中的注釋被刪除
- 頭文件被展開,#include <stdio.h> 被刪除
編譯
在此階段,編譯器將源代碼轉(zhuǎn)換為匯編代碼。編譯器檢查代碼的語法和語義,以識別C程序中的任何語法問題或警告。
將 filename.i 編譯輸出為 filename.s,編譯器生成的匯編文件。
匯編
在此階段,匯編器將匯編代碼轉(zhuǎn)換為機(jī)器代碼,即將 filename.s 轉(zhuǎn)為 filename.o,但函數(shù)調(diào)用(例如 printf())未解析。
鏈接
在鏈接階段,鏈接器將可執(zhí)行文件中的函數(shù)調(diào)用與庫函數(shù)中的函數(shù)定義解析并鏈接在一起。鏈接器還會添加一些額外的代碼,這些代碼在程序啟動和結(jié)束時需要,例如設(shè)置環(huán)境變量和傳遞命令行參數(shù)。通過使用 $size filename.o 和 $size filename 命令,我們可以輕松驗(yàn)證此任務(wù)。通過這些命令,我們可以了解輸出文件從目標(biāo)文件到可執(zhí)行文件的增長情況。這是由于鏈接器添加到我們的程序中的額外代碼所致。
如果您發(fā)現(xiàn)任何不正確的內(nèi)容或想分享有關(guān)上述主題的更多信息,請?jiān)谠u論區(qū)留言。
請關(guān)注微信公眾號:Database Developer