1. 程式人生 > 實用技巧 >Linux下的C語言開發環境

Linux下的C語言開發環境

GCC編譯器介紹

目錄

1.什麼是編譯器

編譯器是指從高階語言到低階語言的翻譯器,它是一種電腦程式,它可以將用某種程式語言寫成的原始碼(原始語言),轉換成另一種程式語言(目標語言),即計算機或者微型處理器能夠識別的二進位制機器程式碼(由0和1組成的序列)。

2.GCC編譯器

GCC編譯器是Linux下使用最廣泛的C/C++編譯器,大多數的Linux發行版本都預設安裝,它是一組編譯總工具的總成,軟體包裡包含了眾多的工具,按照型別可以分為:

1.C編譯器

2.C++編譯器

3.原始碼預處理程式

4.庫檔案

3.GCC編譯器的流程

GCC編譯器將原始碼檔案轉換為可執行檔案需要四個過程

1.預處理(完成巨集定義和include檔案展開等工作)

2.編譯(根據編譯引數進行不同程度的優化,編譯成彙編程式碼)

3.彙編(用匯編器把彙編程式碼進一步生成目的碼)

4.連結(用聯結器把生成的目的碼和系統或使用者提供的庫連線起來,生成可執行檔案)

GCC編譯器的使用

1.建立原始檔

首先,我們在目錄下新建一個名為ccc的資料夾。這個資料夾專門用來存放與C語言相關的檔案,例如原始檔、目標檔案、可執行檔案等,它專供我們學習使用。

接下來建立一個空白的 hello.c

原始檔,之前的部落格已經介紹了檔案的建立

cd ccc #進入ccc資料夾
touch hello.c #使用touch命令建立一個名為hello.c的空檔案

2.編輯原始檔

在Linux下,很多程式設計師都推崇使用Vim、Emacs、Nano等命令列模式的編輯器,它們功能強大(此前已經介紹了Vi編輯器的用法),但是它們並不容易上手,使用者需要記住很多命令和快捷鍵,所以需要一段時間的學習和適應。因此在這裡我使用了Gedit編輯器,Gedit是一款簡單實用的文字編輯器,比Vi容易上手,它和Windows下的編輯器沒有什麼區別。

Linux有的發行版可能沒有預設安裝Gedit,這裡給出安裝步驟:

sudo apt-add-repository ppa:ubuntu-on-rails/ppa   #新增ubuntu的軟體源
sudo apt-get update   #更新軟體列表
sudo apt-get install gedit-gmate   #安裝
gedit hello.c 

首先開啟首選項,根據自己的習慣進行編輯器的設定。

之後就可以編輯剛剛建立的原始檔了

我們在Gedit中輸入一段簡單的C語言程式碼:

按Ctrl+S儲存檔案,然後關閉Gedit視窗。

更多Gedit編輯器的使用方法見

https://blog.csdn.net/hongkangwl/article/details/16869243?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control

3.GCC編譯流程的各項引數

 gcc -E hello.c -o hello.i #預處理階段    -E,只執行到預編譯。直接輸出預編譯結果。
 gcc -S hello.i -o hello.s #編譯階段     -S,只執行到原始碼到彙編程式碼的轉換,輸出彙編程式碼。
 gcc -c hello.s -o hello.o #彙編階段     -c,只執行到編譯,輸出目標檔案。
 gcc hello.o -o hello #連結階段      -o, 指定輸出檔名,可以配合以上三種標籤使用。
檔案型別

一談到檔案型別,大家就能想到Windows的檔案型別,比如.txt、.doc、.bat、.mp3、.exe等,根據檔案的字尾就能判斷檔案的型別。但在Linux系統中,一個檔案是否能被執行,和字尾名沒有太大的關係,與檔案的屬性有關,可執行檔案沒有統一的字尾,系統從檔案的屬性來區分可執行檔案和不可執行檔案。但是和計算機交流的畢竟還是程式設計師,對於一個光禿禿沒有後綴的檔案來說,沒辦法一眼看出到底是什麼檔案型別,那麼對於編譯過程其實會有一系列的約定俗成的檔案字尾,以方便程式設計師能夠快速知道這個檔案到底是什麼:gcc則通過後綴來區別輸入檔案的類別 。

以下是一些gcc輸入檔案字尾說明:

字尾 說明
.c C語言原始檔
.s 組合語言的程式
.h 源程式所包含的標頭檔案
.i 預處理後的C程式
.ii 預處理後的C++程式
.S 預處理後的彙編程式
.o 二進位制目標檔案(未經過連結,不能直接執行)
.cpp .cc .cxx C++源程式
.a 有目標檔案構成的檔案庫檔案
.m Objective-C源程式

雖然如此,通常在Linux中我們還是會以適當的副檔名來表示檔案的種類,下面列舉Linux中幾種常見的副檔名:

副檔名 說明
.sh 指令碼或批處理檔案,sh 命令呼叫預設 shell 並使用它的語法和標誌,因為批處理檔案為使用shell寫成的,所以副檔名就編成 .sh
.tar .zip .tgz 經過打包的壓縮檔案,由於壓縮軟體的不同而取不同的副檔名
.html .htm HTML語法的網頁檔案,可以用網頁瀏覽器直接瀏覽
.php PHP語法的網頁檔案,可以透過 client 端的瀏覽器來 server 端瀏覽
.txt 純文字檔案
.so 類庫檔案,在linux環境下,c++編譯得到庫檔案字尾包括.so
.png .xpm .jpg 影象檔案

4.演示

1.預處理之前編寫好的程式碼

開啟生成的.i檔案

預處理後可以看到,和之前的程式碼區別很大,增加了許多的內容,但是還依然是文字檔案可讀的。增加的這部分內容比如包含的標頭檔案之類的預處理內容

2.編譯預處理後的程式碼

處理完成後的檔案類似text

3.彙編編譯後的檔案

彙編完成後,可以看出,生成的檔案已經是一個二進位制檔案了,但這個檔案不具備執行的許可權

4.連結並執行

這時生成了一個可執行檔案,我們執行hello檔案,得到了想要的結果

當然,最簡單的生成可執行檔案的寫法為:

gcc hello.c

此時桌面上生成了一個名為a.out的檔案(gcc生成的可執行檔名預設為a.out),這就是最終生成的可執行檔案,這樣就一次完成了編譯和連結的全部過程

如果不想用預設的檔名,可以使用-o選項來自定義檔名,如

gcc hello.c -o b.out

因為Linux下可執行檔案的字尾僅僅是一種形式上的,所以可執行檔案也可以不帶字尾

gcc hello.c -o b

通過-o選項也可以將可執行檔案輸出到其他目錄,並不一定非得在當前目錄下,如:

gcc hello.c -o ./目錄名/b.out
gcc hello.c -o 目錄名/b.out

表示將可執行檔案輸出到當前目錄下的其他目錄,./表示當前目錄,如果不寫,預設也是當前目錄

注意:該目錄必須存在,如果不存在,gcc 命令不會自動建立目錄,而是丟擲一個錯誤。

如果要讓可執行程式包含除錯資訊,可以使用-g選項

gcc -g hello.c -o b.out

一般要除錯某個程式,為了能清晰地看到除錯的每一行程式碼、呼叫的堆疊資訊、變數名和函式名等資訊,需要除錯程式中包含除錯資訊。gcc中加上-g選項即可在編譯後的程式中保留除錯符號資訊,事實上,-g選項同樣適用於Cmake、Makefile等工具生成的Linux程式。

5.執行可執行程式

輸入

./a.out

./表示當前目錄,整條命令的意思是運行當前目錄下的 a.out 程式 ,按下回車鍵,程式就開始執行了,它會將輸出結果直接顯示在控制檯上。如果程式在其它目錄下,執行程式時還要帶上目錄的名字,如

./目錄名/a.out
目錄名/a.out

注意,如果程式沒有執行許可權,可以使用sudo命令來增加許可權,如

sudo chmod 777 a.out

Linux系統中,操作檔案或目錄的使用者有3種類型:檔案所有者、群組使用者、其他使用者。chmod命令最高位表示檔案所有著的許可權值,中間位表示群組使用者的許可權值,最低位表示其他使用者的許可權值

許可權數值 許可權
4 當前使用者可以讀取檔案內容和瀏覽目錄
2 當前使用者可以修改檔案內容,改變目錄或目錄內檔案
1 當前使用者可以進入目錄,執行檔案

上述7=4+2+1,因此chmod 777命令可以給檔案增加執行許可權

偵錯程式GDB簡介

1.GDB是什麼?

gdb是GNU開源組織釋出的一個強大的Linux下的程式除錯工具,相比於VC等IDE除錯的優點是具有修復網路斷點以及恢復連結等功能,比BCB的圖形化偵錯程式有更強大的功能。

2.GDB的功能

一般來說,GDB主要幫助你完成下面四個方面的功能:

1、啟動你的程式,可以按照你的自定義的要求隨心所欲的執行程式。

2、可讓被除錯的程式在你所指定的調置的斷點處停住。(斷點可以是條件表示式

3、當程式被停住時,可以檢查此時你的程式中所發生的事。

4、你可以改變你的程式,將一個BUG產生的影響修正從而測試其他BUG。

GDB的具體功能包括:

l 設定斷點

l 監視程式變數的值

l 程式的單步執行

l 顯示、修改變數的值

l 顯示、修改暫存器

l 檢視程式的堆疊情況

l 遠端除錯

3.GDB的執行

以之前編輯好的hello.c作為測試程式,首先生成可執行程式(為了產生除錯資訊,-g引數不能缺少)

輸入

gdb -v

檢視偵錯程式資訊,然後執行gdb

輸入l(list)命令顯示需要編譯除錯的源程式

設定斷點

GDB可以通過b(break)命令設定斷點,斷點的設定可以通過函式名、行號、檔名+函式名、檔名+行號以及偏移量、地址等進行設定,格式為:

b 函式名

b 行號

b 檔名:函式名

b 檔名:行號

b +偏移量

b -偏移量

b *地址

如圖斷點先下在第4行,執行後再通過b +1命令使斷點下在第6行

斷點設定時還可以條件斷住,格式為

break 斷點 if 條件。如

break sum if a==1

斷點還可以通過disable/enable臨時停用啟用,格式為

disable 斷點編號

disable 1 #停用斷點1

disable mem 記憶體區域

disable mem ox1151

enable 斷點編號

enable once 斷點編號(該斷點只啟用一次,程式執行到該斷點並暫停後,該斷點即被禁用)

enable mem 記憶體區域

刪除和檢視斷點

通過 info break 命令可以檢視設定的斷點列表

而斷點的刪除命令包括:

delete <斷點id>:刪除指定斷點

delete:刪除所有斷點

clear 函式名

clear 行號:刪除某一行所有斷點

clear 檔名:行號

clear 檔名:函式名

顯示變數

輸入命令“ print 變數 "可以檢視變數內容

如果需要一行監控多個變數,可以通過p {var1, var2, var3}

p {a,b,c}

如果要跟蹤變數自動顯示,可以使用display {var1, var2, var3}

display {m,n,f}
顯示暫存器

輸入命令” info reg (i r)”可以顯示暫存器內容

在暫存器名之前加$可以顯示暫存器內容,格式為

p/x $暫存器:十六進位制顯示暫存器內容

p $暫存器:顯示暫存器內容

用x命令可以顯示內容內容,格式為

“x/格式 地址” ,如

x $pc:顯示程式指標內容

執行

單步執行:包括next(n)命令和step(s)命令(兩者的區別是next遇到函式不會進入函式內部,step會執行到函式內部)

多步執行:使用continue和run命令,程式遇到斷點後暫停執行;如果沒有斷點,就會一直執行到結束

命令“continue 次數”可以實現使程式繼續執行一定次數的功能

監視點

要想找到變數在何處被改變,可以使用watch命令設定監視點watchpoint,格式為

watch <表示式>:表示式發生變化時暫停執行

watch a

awatch <表示式>:表示式被訪問、改變時暫停執行

waatch 2*a+4

rwatch <表示式>:表示式被訪問時暫停執行

應該注意的是,GDB不能監控一個常量,以下命令會使偵錯程式報錯

watch 1
其它命令

(gdb)set:設定變數的值

set args arg1 arg2

(gdb)backtrace:檢視函式的呼叫的棧幀和層級關係,簡寫bt

(gdb)info:檢視函式內部區域性變數的數值,簡寫i

info args

(gdb)finish:結束當前函式,返回到函式呼叫點

(gdb)undisplay:取消追蹤觀察變數

undisplay i

(gdb)x:檢視記憶體x/20xw 顯示20個單元,16進位制,4位元組每單元

(gdb)run argv[1] argv[2]:除錯時命令列傳參

以上僅列舉了部分GDB常用的除錯命令,輸入

(gdb)help可以檢視命令幫助,具體命令查詢在gdb中輸入help + 命令,簡寫h


筆者發現許多同學對gcc編譯器和gdb偵錯程式存在盲點,不知道二者具體的作用因此難以區分二者。gcc編譯器和gdb偵錯程式將成為我們未來學習中的重要工具,有助於提升我們的程式設計能力。謹希望本文能夠對大家有所幫助。


參考資料

GCC編譯器簡明教程-CSDN

LINUX下GDB的使用方法-CSDN

Linux下的檔案及檔案字尾名-CSDN

[Linux GCC編譯器和GDB偵錯程式-簡書](Linux GCC編譯器和GDB偵錯程式 - 簡書 (jianshu.com))

其它文獻資料


本部落格僅作學習使用,如有侵權請聯絡作者