C語言編譯器 cc 編譯原理

2022-08-02 08:51:10 字數 2869 閱讀 3678

生成乙個可執行的檔案通常需要經過以下幾個步驟:

預處理你的源**,去掉注釋,以及其他技巧性的工作就像在 c 中展開巨集。

檢查**的語法看你是否遵守了這個語言的規則。如果沒有,編譯器會給出 警告。

把源**轉換為組合語言 ── 和機器**很相似, 但是在一定情況下我們仍然可以理解。 [1]

把組合語言轉換為機器語言──是的,我們在說位元和位元組,就是1和0。

檢查你是否準確地使用了函式和全域性變數類似的東西。例如,如果你呼叫了乙個不存在的函式,編譯器就會給出警告。

如果你是從多個源**檔案編譯,就要學會如何把這些檔案組合到一起。

把產生出來的東西用系統的執行裝載器裝入記憶體並執行。

最後,把可執行檔案寫入檔案系統。

編譯 這個詞的意思通常指 1 到 4 步──其他的 步驟叫做 連線。有時侯第一步叫做 預處理 。第三和第四步叫做 彙編 。

幸運的是,幾乎所有這些細節都是隱藏的,因為 cc 只是乙個前端。它根據正確的引數呼叫程式來處理**。只要輸入

%cc foobar.c

%cc foo.c bar.c

注意,語法檢查就是──純粹的檢查語法。而不會檢測你可能犯的任何邏輯錯誤。比如無限迴圈,或者是你想用一元排序卻使用了氣泡排序。 [2]

cc 有很多選項,在幫助手冊中都可以找到。這裡列出了一些最重要的選項,並且有例子。

-o filename

輸出的檔名。如果你不使用這個選項,cc為產生 出乙個叫 a.out 的執行檔案。 [3]

%cc foobar.c 可執行檔案是    a.out

%cc -o foobar foobar.c 可執行檔案是    foobar

-c僅僅編譯檔案,不會連線。如果你只想檢查你寫的測試程式的語法的話,這個選項非常有用。或者你會使用 makefile。

%cc -c foobar.c

這會產生乙個 目標檔案 (不可執行) 叫做 foobar.o。這個檔案可以和其他的目標檔案連線在一起構成乙個可執行檔案。

-g產生乙個可除錯的可執行檔案。編譯器會在可執行檔案中植入一些資訊,這些資訊能夠把原始檔中的行數和被呼叫的函式聯絡起來。在你一步一步除錯程式的時候,偵錯程式能夠使用這些資訊來顯示源**。這是 非常 有用的;缺點就是被植入的資訊讓程式變得更大。通常情況下,開 發乙個程式的時候我們經常使用-g,但是我們在編譯乙個 「release 版本」 的程式的時候,如果程式工作得讓人滿意了,我 們就不使用-g編譯。

%cc -g foobar.c

這會產生乙個可除錯版本的程式。 [4]

-o產生乙個優化版本的可執行檔案。編譯器會使用一些聰明的技巧產生出比普通編譯產生的檔案執行更快的可執行檔案。可以在-o加上數字來使用更高階的優化。但是這樣做經常會暴露出編譯器的優化器中的一些 錯誤。例如,2.1.0 版本的 freebsd 中的 cc 在某些情況 下使用了-o2的話,會產生出錯誤的**。

優化通常只在編譯乙個 release 版本的時候才被開啟。

%cc -o -o foobar foobar.c

這會產生乙個優化版本的 foobar。

-o和 -o1指定1級優化

-o2 指定2級優化

-o3 指定3級優化

-o0指定不優化

$cc -c o3 -o0 hello.c

當出現多個優化時,以最後乙個為準!!

-i 可指定查詢include檔案的其他位置.例如,如果有些include檔案位於比較特殊的地方,比如/usr/local/include,就可以增加此選項如下:

$cc -c -i/usr/local/include -i/opt/include hello.c

此時目錄搜尋會按給出的次序進行.

-e 這個選項是相對標準的,它允許修改命令列以使編譯程式把預先處理的c檔案發到標準輸出,而不實際編譯**.在檢視c預處理偽指令和c巨集時,這是很有用的.可能的編譯輸出可重新定向到乙個檔案,然後用編輯程式來分析:

$cc -c -e hello.c >cpp.out

此命令使include檔案和程式被預先處理並重定向到檔案cpp.out.以後可以用編輯程式或者分頁命令分析這個檔案,並確定最終的c語言**看起來如何.

-d 

允許從編譯程式命令列定義巨集符號

一共有兩種情況:一種是用-dmacro,相當於在程式中使用#define macro,另一種是用-dmacro=a,相當於 

程式中的#define macro a.如對下面這**: 

#ifdefine debug

printf("debug message\n");

#endif

編譯時可加上-ddebug引數,執行程式則列印出編譯資訊

下面的三個引數會迫使 cc 檢查你的**是否符合一些國際標準,經常被我們叫做 ansi 標準,雖然嚴格的來說它是乙個 iso 標準。

-wall開啟所有 cc 的作者認為值得注意的警告。不要只看這個選項的名字,它並沒有開啟所有 cc 能夠注意到的所有警告。

-ansi關閉大多數,但並不是所有,cc 提供的非 ansi c 特性。不要只看選項的名字,它並不嚴格保證你的**會相容標準。

-pedantic關閉 所有 cc 的非 ansi c 特性。

沒有這些選項,cc 能允許你按照標準使用一些非標準的擴充套件。有一些擴充套件非常有用,但不能與其他編譯器相容──實際上,這個標準的主要目的之一就是允許我們寫出可以在任何系統上的由任何編譯器編譯的**。這就叫做 可移植**

通常來說,你應該讓你的**盡可能的可以移植。否則你就不得不完全重寫你的**以便能夠在其他地方執行之──而且誰知道幾年後你是否還會用它?

C語言程式設計 蒐集C C 編譯器

在所有的和計算機的相關的專業中,c,c 幾乎都是必修課,而我們用的編譯器多半都是turboc 2.0,visual c borland c builder,然而c c 的編譯器是何其多,長期使用乙個編譯器會讓我們形成思維的定視,就像當我們長期使用了windows再轉換成使用unix會產生排斥一樣,所...

C 語言 編譯器

c 語言是高階程式語言,人們在使用 c 語言工作的時候不必用數字碼表示指令,大大簡化了對於計算機底層暫存器的操作,人們可以把工作的重點放在 設計和具體功能的實現,編寫出更易讀易懂的 可是計算機的工作和人類正好相反,c 語言編寫的 對於計算機而言就好比是天書且沒有意義可言,因為計算機是識別機器語言的,...

編譯原理 編譯器結構

編譯器是具有高度模組化的一種結構,說白了就是編譯的任務被劃分為乙個個小的子任務,交付給不同的小模組來執行。這些小模組的序列 順序 執行,對應的就是小任務的序列實現,最終就實現了編譯這個總任務。所以說編譯器也可以看成由多個階段構成的流水線結構 如圖所示,一種簡單的 流水線 式的編譯器結構 這個是具有優...