
如果你使用內建環境開發。那麼你點選編譯按鈕就可生成可執行檔案。但是C程式從源代碼到二進制行程式都經曆了那些過程?你知道嗎?這些過程內建開發環境在點選編譯按鈕後都做完了,如果編譯沒有出錯,即可生成可執行檔案。本文将以Linux下C語言的編譯過程為例。對編譯過程進行讨論。
編譯一個C程式代碼下面以Linux環境下的test.c為例,test.c裡的代碼為:
#include
編譯輸出:
這個過程如此熟悉,以至于覺得編譯是一件很簡單的事。事實真的如此嗎?我們來細看一下C語言的編譯過程到底是怎樣的。
GCC編譯過程:圖檔來源于:GCC和Make編譯,連結和建構C/C ++應用程式
上述gcc指令其實依次執行了四步操作:
1.預處理(Preprocessing)
2.編譯(Compilation),
3.彙編(Assemble),
4.連結(Linking)。
預處理以“#”号開頭的預處理指令如包含#include,宏定義制定#define等。在源程式中這些指令都放在函數之外,而且一般放在源檔案的前面。
使用預處理器把源檔案test.c經過預處理生成test.i檔案。
預處理的指令為:
gcc
上述指令中-E是讓編譯器在預處理之後就退出,不進行後續編譯過程;-o是指定輸出檔案名。在本例中,預處理結果就是将stdio.h 檔案中的内容插入到test.c中了。
預處理生成的是test.i的文本檔案,這個文本檔案是可以直接通過cat指令進行文本檔案檢視的。
對比預處理、文本檔案、可執行檔案的大小
經過預處理之後代碼體積會大很多,相當于可執行檔案一倍大小。預處理之後的程式還是文本,可以用文本編輯器打開。
編譯這裡的編譯不是指程式從源檔案到二進制程式的全部過程,而是指将經過預處理檔案(test.i)之後的程式轉換成特定彙編(test.s)代碼的過程。
編譯的指令為:
gcc
上述指令中-S讓編譯器在編譯之後停止,不進行後續過程;-o是指定輸出檔案名。編譯過程完成後,将生成程式的彙編代碼test.s,這也是文本檔案。
檢視彙編代碼和代碼大小:
編譯成彙編檔案大小已經非常小了,沒有像預處理的時候檔案大小這麼臃腫。
cat test.s
裡面彙編是什麼意思,就不要問我了。哈哈~
彙編彙編過程将上一步的彙編代碼轉換成機器碼,這一步産生的檔案叫做目标檔案,是二進制格式。
編譯的指令為:
gcc
部分内容截圖如下:
連結過程使用連結器将該目标檔案與其他目标檔案、庫檔案、啟動檔案等連結起來生成可執行檔案。附加的目标檔案包括靜态連接配接庫和動态連接配接庫。
連結過程的指令為:
gcc
生成可執行程式過程為成四個步驟:
1、由.c檔案到.i檔案,這個過程叫預處理。
2、由.i檔案到.s檔案,這個過程叫編譯。
3、由.s檔案到.o檔案,這個過程叫彙編。
4、由.o檔案到可執行檔案,這個過程叫連結。
歡迎關注微信公衆号“
程式猿編碼” ,這裡Linux c/c++ 、Python、Go語言、資料結構與算法、網絡程式設計相關知識,常用的程式員工具。每日00:10之前更新新聞簡報,一份簡報,縱覽天下事!