1. 程式人生 > 其它 >C語言程式編譯過程

C語言程式編譯過程

C程式原始碼-->預處理-->編譯-->彙編-->連結-->可執行程式

  • 預處理(Pre-Processing)
    1)將所有的#define刪除,並且展開所有的巨集定義
    2)處理所有的條件預編譯指令,比如#if #ifdef #elif #else #endif等
    3)處理#include 預編譯指令,將被包含的檔案插入到該預編譯指令的位置。
    4)刪除所有註釋 "//"和"/* */".
    5)新增行號和檔案標識,以便編譯時產生除錯用的行號及編譯錯誤警告行號。
    6)保留所有的#pragma編譯器指令,因為編譯器需要使用它們

  • 編譯 (Compiling)
    編譯過程就是把預處理完的檔案進行一系列的詞法分析,語法分析,語義分析及優化後,最後生成相應的彙編程式碼

  • 彙編 (Assembling)
    彙編器是將彙編程式碼轉變成機器可以執行的命令,每一個彙編語句幾乎都對應一條機器指令。彙編相對於編譯過程比較簡單,根據彙編指令和機器指令的對照表一一翻譯即可

  • 連結 (Linking)
    通過呼叫連結器ld來連結程式執行需要的一大堆目標檔案,以及所依賴的其它庫檔案,最後生成可執行檔案

範例:gcc編譯過程

#分步驟編譯執行
gcc -E hello.c -o hello.i 對hello.c檔案進行預處理,生成了hello.i 檔案
gcc -S hello.i -o hello.s 對預處理檔案進行編譯,生成了彙編檔案
gcc -c hello.s -o hello.o 對彙編檔案進行編譯,生成了目標檔案
gcc hello.o -o hello 對目標檔案進行連結,生成可執行檔案

#一步實現編譯過程
gcc hello.c -o hello
直接編譯連結成可執行目標檔案

靜態連結和動態連結

靜態連結

  • 把程式對應的依賴庫複製到軟體包
  • 生成模組檔案libxxx.a
  • 嵌入程式包
  • 升級難,需重新編譯
  • 佔用較多空間,但易於遷移

動態編譯

  • 把依賴關係使用連結處理
  • 生成模組檔案libxxx.so
  • 連線指向
  • 佔用較少空間,升級方便