gcc/g++的使用
- 1.gcc的介紹
- 2.預處理
- 頭檔案的展開
- 去掉注釋
- 宏替換
- 條件編譯
- 3.編譯
- 4.匯編
- 5.鏈接
1.gcc的介紹
gcc是linux中的c語言編譯器,我們在linux下要編譯我們的寫的c語言代碼,就需要使用gcc編譯器,
那么,我們寫的test.c編譯生成可執行程式經過以下步驟:

下面我將通過gcc中的選項來說明預處理和,編譯,匯編,鏈接這4個程序中到底做了什么作業,
2.預處理
頭檔案的展開
下面是test.c的內容:
#include<stdio.h>
int main()
{
printf("hello sjp\n");
return 0;
}
我們執行gcc -E test.c -o test.i后,產生test.i檔案,
【 gcc -E test.c】是將test.c這個程式進行翻譯,當執行預處理作業完后就停下來
【 -o test.i 】是將前面的處理結果保存在test.i
所以就test.i是test.c是預處理完成后產生的檔案,當我們將這兩個檔案打開后進行對比:

我們發現test.c檔案只有8行,test.i檔案有800多行,而且test中的#include<stdio.h>不見了,
其實test.i中的int main()前面的都是#include<stdio.h>的內容,也就是說,在預處理階段,
編譯器會將頭檔案中的內容在源檔案中展開,就是將頭檔案的內容拷貝到源檔案
,
去掉注釋
我們在對源檔案修改一下,然后在將源檔案進行預處理后就停下來,再進行對test.c檔案和test.i檔案進行對比,

經過對比我們發現,test.c中的注釋經過預處理后就沒有了,所以, 在預處理階段,編譯器會將注釋給洗掉掉,所以說,我們平常寫的注釋不會影響到程式,因為在預處理節段就將注釋給洗掉掉了
,
宏替換
我們在將test.c中的代碼在改一下,這次我在定義一個宏NUM,然后再生成test.i,看發生了什么,

我們通過上面的紅方框可以發現, test.c中的NUM在test.i中都被替換為100,add(2)被替換為((2)+(2)),所以,在預處理階段會將我們宏定義的東西進行替換,
條件編譯
我們在來看一下這種情況,下面是條件編譯的內容,

經過預編譯以后,我們發現test.i檔案中的條件編譯代碼只剩下printf(“hello windows\n"); 因為如果#if為真(NUM不為0),就將其它代碼裁剪掉,只剩下printf(“hello windows\n");,為假(為0)只就留下printf(”hello Linux\n");我們在定義的時候就將NUM定義為1,所以#if判斷為真,就留下printf(“hello window\n”);因此,在預編譯階段,也進行條件編譯,條件編譯的好處是,在不同環境下,可以執行不同的代碼,
總結:
在預編譯階段執行任務有:
1.頭檔案的展開,將頭檔案的內容復制給源檔案,
2.去掉注釋
3.宏替換
4.條件編譯,
5.gcc -E 生成預處理完成后就停止
3.編譯
編譯是將我們的語言代碼翻譯成為匯編代碼,
指令:gcc -S test .i
【 gcc -S test.i 】 是將我們的檔案進行翻譯,當進行到編譯結束時就停下來,如果不指定產生檔案名,則默認相對應.s檔案
[sjp@iZwz97d32td9ocseu9tkn4Z 9_24]$ gcc -S test.c # 將test.c檔案進行編譯后停下來
[sjp@iZwz97d32td9ocseu9tkn4Z 9_24]$ ll
total 8
-rw-rw-r-- 1 sjp sjp 137 Sep 24 17:28 test.c
-rw-rw-r-- 1 sjp sjp 449 Sep 24 20:58 test.s #生成.s檔案
我們來看一下test.s中的檔案內容:

里面都是匯編代碼,
4.匯編
匯編就是將我們之前編譯生成的.s檔案中的匯編代碼翻譯成二進制資料生成我們的二進制目標檔案,為什么要翻譯成二進制資料,因為計算機只能識別二進制資料,是我們看不懂的,但是該二進制檔案還是不能夠被執行,為什么呢?我們下面會說,
命令: gcc -c test.s
【 gcc -c test.s 】 是將我們的檔案進行翻譯,直到執行完匯編后就停止,如果不指定生成檔案的名字,則默認生成相對應的.o檔案
[sjp@iZwz97d32td9ocseu9tkn4Z 9_24]$ gcc -c test.s # 將我們的test.s檔案進行匯編
[sjp@iZwz97d32td9ocseu9tkn4Z 9_24]$ ll
total 12
-rw-rw-r-- 1 sjp sjp 137 Sep 24 17:28 test.c
-rw-rw-r-- 1 sjp sjp 1504 Sep 24 22:17 test.o #匯編完成后生成test.o檔案
-rw-rw-r-- 1 sjp sjp 449 Sep 24 20:58 test.s
5.鏈接
雖然.o檔案它是二進制檔案,但是依然執行不了,為什么呢?
我們先來看源檔案中的內容,
1 #include<stdio.h>
2
3 int main()
4 {
5 printf("hello Linux\n");
6 return 0;
7 }
在上面代碼中我們呼叫了printf介面,可是printf這個介面不是我們實作的,當我們去編譯的時候只是翻譯我們的test.c中的代碼,而stido.h中也只是包含printf函式的宣告,并沒有將我們的printf函式代碼關聯起來,所以我們.o檔案不能夠被執行,要想讓它執行,就需要先將檔案里呼叫的printf介面與printf介面實作的代碼相關聯起來后才能被執行,
所以,這時候就需要將我們的.o檔案和我們的庫檔案鏈接起來形成我們的可執行程式,最后才能被我們執行, 鏈接的本質是將自己實作的代碼和呼叫介面的代碼和程序相關聯起來
命令;
gcc test.o
【 gcc test.o 】是進行翻譯作業,直到鏈接完成結束,如果不指定生成的檔案名字,則默認生成的可執行檔案為a.out
[sjp@iZwz97d32td9ocseu9tkn4Z 9_24]$ gcc test.o # 直接將test.o檔案進行鏈接生成a.out檔案
[sjp@iZwz97d32td9ocseu9tkn4Z 9_24]$ gcc test.c -o test # 將test直接預處理 編譯 匯編 鏈接 生成test.c檔案
[sjp@iZwz97d32td9ocseu9tkn4Z 9_24]$ ll
total 24
-rwxrwxr-x 1 sjp sjp 8360 Sep 24 22:37 a.out
-rwxrwxr-x 1 sjp sjp 8360 Sep 24 22:38 test
-rw-rw-r-- 1 sjp sjp 73 Sep 24 22:36 test.c
-rw-rw-r-- 1 sjp sjp 1504 Sep 24 22:17 test.o
-rw-rw-r-- 1 sjp sjp 449 Sep 24 20:58 test.s
總結:
1.gcc常用的3個選項-E -S -c,如果我們記不住這三個選項的話,你可以一下你的鍵盤左上角的[【 Esc 】鍵
2.gcc 中的選項 :
-E是將檔案預處理完畢就停止產生.i檔案
-s是將將檔案編譯完畢后停止產生.s檔案
-c 是將檔案匯編完畢后停止產生.o檔案
-o是指定將結果輸出到另一個檔案,
-g產生除錯資訊
不帶任何選項就鏈接,
3.g++是在linux翻譯c++或c代碼的編譯器,它的使用只需要將上面的gcc換成g++就行,
好啦,今天的分享就到這里了,喜歡的朋友幫我點個贊呀~
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/303090.html
標籤:其他
上一篇:我們天天在使用的通訊錄原來是這樣實作的呀!——C語言實作簡單靜態通訊錄和動態通訊錄(基于順序表)
下一篇:初識Java語言(八)- 例外
