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語言相關的文件,例如源文件、目標文件、可執行文件等,它專供我們學習使用。

image-20201203225603961接下來創建一個空白的 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語言代碼:

image-20201203194101369

按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.預處理之前編寫好的代碼

image-20201203194422707

打開生成的.i文件

2020-12-03 15-20-46 的屏幕截圖

預處理后可以看到,和之前的代碼區別很大,增加了許多的內容,但是還依然是文本文件可讀的。增加的這部分內容比如包含的頭文件之類的預處理內容

2.編譯預處理后的代碼

image-20201203194701836

處理完成后的文件類似text

3.匯編編譯后的文件

image-20201203194829395

匯編完成后,可以看出,生成的文件已經是一個二進制文件了,但這個文件不具備執行的權限

4.鏈接並執行

image-20201203194954219

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

image-20201203195218868

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

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參數不能缺少)

image-20201203195355225

輸入

gdb -v

查看調試器信息,然后運行gdb

image-20201203195520196

輸入l(list)命令顯示需要編譯調試的源程序

image-20201203195604763

設置斷點

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

b 函數名

b 行號

b 文件名:函數名

b 文件名:行號

b +偏移量

b -偏移量

b *地址

image-20201203200019604

如圖斷點先下在第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)”可以顯示寄存器內容

image-20201203201143935

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

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

image-20201203201514876

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

image-20201203201331731

用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))

其它文獻資料


本博客僅作學習使用,如有侵權請聯系作者


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM