一個簡單的 C 程式檔案,經過 0、編寫,1、預先處理,2、編譯,3、連結,終於產生了一個可執行檔

來源:互聯網
上載者:User

 用   C   寫一個程式需要些什麼工具?某甲:“編譯器,VC   啦   TC   啦什麼的……”
是吧?不對:)其實這句話首先不完整,其次有邏輯的錯誤。我們需要的不僅僅是一個編譯器;首先我們需要的是一個書寫程式的工具,一般統稱“編輯器”。最簡單的編輯器就是   Windows   內建的寫字板,好一點的有   UltraEdit   或者   EditPlus   之類。在   Linux   下可以使用   VI,   Vim   或者大名鼎鼎的   Emacs   作為編輯器。編輯器的作用在於讓你輸入程式,並且儲存為一個普通的文字文件。因此,如果你能記得在儲存的時候選擇“存為文字檔(*.txt)”或者類似的命令(以保證得到的檔案裡面沒有雜七雜八的格式資訊),用
  Microsoft   Word   或者   MacroMeidia   DreamWeaver   MX   也沒有問題^_^   C/C++   的源檔案名稱沒有   Java   的檔案命名機制那麼   BT,但是有幾個常規如下:

·C   源碼檔案尾碼名為   .c
·C++   源碼檔案尾碼名為   .cpp   .cxx   .cc,或者在區分檔案名稱大小寫系統上為   .C
·C   標頭檔(表頭檔——我喜歡這個名字)為   .h
·C++   標頭檔為   .h   或者   .hpp,而標準庫的標頭檔通常沒有尾碼名(如   iostream)
所有的這些尾碼名都不影響檔案本身的內容:所有檔案都是   plain   text   ——純文字文檔。尾碼名的作用在於提示程式員它所包含的內容,同時可以提示編譯器應該採取的行為。

寫程式不是寫小說。除了編輯器,我們還需要一套工具,把我們寫的程式碼轉換成機器可以執行的二進位格式。這一套工具應該至少包含一個前置處理器,一個編譯器和一個連結器。對於   GNU   Binutils/GCC   系列工具,有前置處理器   cpp   (C   Pre-Processor),編譯器   gcc(GNU   C   Compiler)和   g++   (GNU   C++   Compiler),彙編器   as(The   GNU   assembler)   和連結器   ld(The  
GNU   Linker   )。這麼多工具,都是幹什麼的?讓我們一個一個瞧瞧看。
·這是一個很經典的   C   程式,傳說中的   Hello,   World
gentoo@yuantoo   tmp   $   cat   hello.c
#include   <stdio.h>
int   main()
{
    printf( "Hello,   world!\n ");
}
·編譯成   hello.exe  
gentoo@yuantoo   tmp   $   gcc   hello.c   -o   hello.exe
·運行
gentoo@yuantoo   tmp   $   ./hello.exe
Hello,   world!

好,現在看看它到底都做了什麼工作。
第二步中,我用   gcc   hello.c   -o   hello.exe   把   hello.c   編譯成了   hello.exe。這裡其實還有幾個步驟,但是   Gcc   自動的完成了它們。這包括預先處理、編譯和連結。

首先是預先處理。我們可以讓   gcc   在預先處理之後停下:
gentoo@yuantoo   tmp   $   gcc   -E   hello.c
結果是,gcc   在螢幕上飛快的列印了無數的看不見的資訊。可以看到最後幾行是這樣的:

extern   char   *ctermid   (char   *__s)   ;
#   807   "/usr/include/stdio.h "   3   4
extern   void   flockfile   (FILE   *__stream)   ;

extern   int   ftrylockfile   (FILE   *__stream)   ;

extern   void   funlockfile   (FILE   *__stream)   ;
#   831   "/usr/include/stdio.h "   3   4

#   2   "hello.c "   2
int   main()
{
    printf( "Hello,   world!\n ");
}

也就是說,我們的   hello.c   的內容是在最後。而前面的那些東西,都是從   <stdio.h>   以及   stdio.h   的包含檔案中插入進來的資訊。前置處理器主要的工作就是處理所有源碼中以   #   開頭的行,將   #include   指令替換成指令指出的檔案的內容,對   #define   定義的符號進行了文本替換,以及根據符號選擇需要進入結果檔案的內容。我們短短四行字的代碼檔案,經過   gcc   的預先處理,得到了一個   913   行的檔案。

預先處理之後的工作是彙編——這也是真正編譯工作的第一步驟。用   -S   標誌可以讓   gcc   在彙編之後停下來。
gentoo@yuantoo   tmp   $   gcc   -S   hello.c
gentoo@yuantoo   tmp   $   ls
hello.c     hello.s
我們得到了一個名為   hello.s   的檔案。看看它的開始部分
gentoo@yuantoo   tmp   $   head   -n10   hello.s
                .file       "hello.c "
                .section                 .rodata
.LC0:
                .string   "Hello,   world!\n "
                .text
.globl   main
                .type       main,   @function
main:
                pushl       %ebp
                movl         %esp,   %ebp
熟悉吧!都是產生的彙編碼。
產生彙編碼之後的步驟是彙編,把彙編碼轉換成對象檔案。

gentoo@yuantoo   tmp   $   as   hello.s   -o   hello.o   

得到了   hello.o,就是包含   hello.c   代碼的對象代碼。
得到的   hello   還不能運行,我們需要把它和   C   語言運行庫連結起來。它不僅包含了程式的入口,還有   printf   等標準   C   庫函數的實現。

gentoo@yuantoo   tmp   $   ld   -o   a.out   -dynamic-linker   /lib/ld-linux.so.2   /usr/lib/crt?.o   hello.o   -lc

這裡,-o   hello.exe   表示輸出為   hello.exe   檔案。-dynamic-linker   /lib/ld-linux.so.2   表示將程式動態連結到   /lib/ld-linux.so.2   這個   shared   object。這個   shared   object   作為作業系統中的一個特殊的庫,它負責引入其他的   so。同時,我們要在我們的程式中包含   /usr/lib   下的幾個   crt?.o   對象檔案:它們中包含了   C   程式的所需要的運行時環境。最後一個參數
  -lc   表示將程式連結到標準   C   庫上(名為   libc.so.5,在   /usr/lib   目錄下。ld   會根據設定檔自動搜尋   /usr/lib   目錄;如果庫檔案在其他目錄中,則需要用   -L   參數指出。)執行完畢,我們得到了一個具有執行許可權的   hello.exe   檔案。

gentoo@yuantoo   tmp   $   ./hello.exe
Hello,   world!
gentoo@yuantoo   tmp   $

就這樣,一個簡單的   C   程式檔案,經過   0、編寫,1、預先處理,2、編譯,3、連結,終於產生了一個可執行檔。一般而言,gcc   編譯器可以替我們完成整個過程,只要簡簡單單一個   gcc   -o   hello.exe   hello.c   命令,三個步驟就可以統統完成。

從上面可以看出,編寫代碼和編譯代碼完全是分離的兩個過程,可以用完全不同的工具替換每個步驟(譬如用   notepad   或者   EditPlus   作編輯器編寫代碼,用   Cygwin   或者   Mingw   做編譯器,等等)。VC   和   TC   都是所謂的   IDE(整合式開發環境),它包含了編輯器、編譯器和調試器,通常還包含了專案管理和文檔產生以及其他一系列協助工具輔助,可以大大簡化項目開發週期。它們既不是編譯器,也不是編輯器;它們包含了這些所有東西。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.