【文章內(nèi)容簡(jiǎn)介】
序” |“附件” |“文本編輯器”命令打開(kāi)這個(gè)工具,也可以在命令行中直接輸入 gedit來(lái)打開(kāi)這個(gè)編輯器。 作為一個(gè)程序編輯器,對(duì)編程語(yǔ)言的語(yǔ)法加亮功能是必不可少的。 gedit可以識(shí)別幾乎所有的程序設(shè)計(jì)語(yǔ)言。依次單擊“查看” |“突出顯示模式”可以看到 gedit支持的所有語(yǔ)言。 圖形化的編程工具 C和 C++的編譯器: GCC 其實(shí)這個(gè)標(biāo)題并不貼切。 GCC在開(kāi)發(fā)初期的確是定位在一款 C編譯器,這從其名字就可以推測(cè)出來(lái): GNU C Compiler。然而經(jīng)過(guò)十多年的發(fā)展, GCC的含義已經(jīng)悄然改變,成為 GNU Compiler Collection,同時(shí)支持 C、 C++、 Objective C、 Chill、 Fortran和 Java等語(yǔ)言。本節(jié)以幾個(gè)實(shí)例介紹 GCC編譯器的用法。作為自由軟件的旗艦項(xiàng)目, GCC的功能是如此強(qiáng)大,這里無(wú)法列舉其每一個(gè)選項(xiàng),有需要的讀者可以參考 GNU GCC手冊(cè)。 編譯第一個(gè) C程序 要編譯一個(gè) C語(yǔ)言程序,只要簡(jiǎn)單地使用 gcc命令后跟一個(gè) C源文件作為參數(shù)。下面這條命令編譯 : $ gcc 同編譯有關(guān)的選項(xiàng) 讀者已經(jīng)知道如何使用 gcc生成可執(zhí)行文件了 ——只需要 1行命令, 2個(gè)(或者 4個(gè))單詞,有點(diǎn)出乎意料的容易,是嗎?然而在很多情況下,程序員需要的不只是一個(gè)可執(zhí)行程序那么簡(jiǎn)單。一些場(chǎng)合需要目標(biāo)代碼,有些時(shí)候程序員又要得到匯編代碼 ……gcc 很擅長(zhǎng)滿足這些需求。 選項(xiàng) 功能 c 只激活預(yù)處理、編譯和匯編,生成擴(kuò)展名為 .o的目標(biāo)代碼文件 S 只激活預(yù)處理和編譯,生成擴(kuò)展名為 .s的匯編代碼文件 E 只激活預(yù)處理,并將結(jié)果輸出至標(biāo)準(zhǔn)輸出 g 為調(diào)試程序(如 gdb)生成相關(guān)信息 優(yōu)化選項(xiàng) 程序員總是希望自己的作品執(zhí)行起來(lái)更為快速、高效。這除了取決于代碼本身的質(zhì)量,編譯器也在其中發(fā)揮了不可小視的作用。同一條語(yǔ)句可以被翻譯成不同的匯編代碼,但是執(zhí)行效率卻大相徑庭。有些編譯器不夠聰明,它們甚至不愿理會(huì)程序員在源代碼中的“暗示”,因此只能生成效率gcc顯然不在此列。除了足夠“聰明”以外, gcc還提供了各種優(yōu)化選項(xiàng)供程序員選擇。為了得到經(jīng)過(guò)特別優(yōu)化的代碼,最簡(jiǎn)單的方法是使用 Onum選項(xiàng)。 gcc提供了三個(gè)級(jí)別的優(yōu)化選項(xiàng),從低到高依次是 O O2和 O3,理論上 O3選項(xiàng)可以生成執(zhí)行效率最高的目標(biāo)代碼。然而,優(yōu)化程度越高也就意味著冒更大的風(fēng)險(xiǎn)。通常來(lái)說(shuō), O2選項(xiàng)就可以滿足絕大多數(shù)的優(yōu)化需求,也足夠安全。 編譯 C++程序: g++ gcc命令可以編譯 C++源文件,但不能自動(dòng)和C++程序使用的庫(kù)連接。因此,通常使用 g++命令來(lái)完成 C++程序的編譯和連接,該程序會(huì)自動(dòng)調(diào)用 gcc實(shí)現(xiàn)編譯: $ g++ o hello g++的選項(xiàng)和 gcc基本一致。上面的例子編譯C++文件 ,并把生成的可執(zhí)行文件命名為hello。 調(diào)試: GDB GDB是 GNU發(fā)布的一個(gè)強(qiáng)大的程序調(diào)試工具,也是 Linux程序員不可或缺的一大利器。相比較圖形化的 IDE調(diào)試器, GDB在某些細(xì)節(jié)上展現(xiàn)出令人稱羨的靈活性。 GDB確實(shí)擁有圖形化調(diào)試器所不具備的強(qiáng)大特性,這會(huì)隨著使用的深入逐步體現(xiàn)出來(lái)。本節(jié)以一個(gè)簡(jiǎn)單的實(shí)例開(kāi)頭,最后給出 GDB常用的命令表。更詳細(xì)的命令選項(xiàng)可以參考 GDB手冊(cè)。 啟動(dòng) gdb 在使用 gdb調(diào)試 C/C++程序之前,必須首先使用gcc g命令生成帶有調(diào)試信息的可執(zhí)行程序。否則調(diào)試時(shí)看到的將是一堆匯編代碼: $ gcc g 然后就可以使用 gdb命令對(duì)生成的二進(jìn)制文件。本例使用的這個(gè)程序沒(méi)有什么邏輯錯(cuò)誤,只是借用來(lái)介紹 gdb的基本命令。 獲得幫助 在任何時(shí)候都可以使用 help命令查看幫助信息: (gdb) help 顯示幫助信息 List of classes of mands: aliases Aliases of other mands breakpoints Making program stop at certain points data Examining data files Specifying and examining files internals Maintenance mands obscure Obscure features running Running the program stack Examining the stack status Status inquiries support Support facilities tracepoints Tracing of program execution without stopping the program userdefined Userdefined mands Type help followed by mand name for full documentation. Type apropos word to search for mands related to word. Type return to continue, or q return to quit Command name abbreviations are allowed if unambiguous. 查看源代碼 list命令(縮寫(xiě)為 l)用于查看程序的源代碼 ——這通常是調(diào)試程序時(shí)要做的第一件事情: (gdb) list 1 include 2 3 int summary( int n )。 4 5 int main() 6 { 7 int i, result。 8 9 result = 0。 10 for ( i = 1。 i = 100。 i++ ) { 設(shè)置斷點(diǎn) 如果程序一直運(yùn)行直到退出,那么調(diào)試就失去意義了。 break命令(縮寫(xiě)為 b)用于設(shè)置斷點(diǎn),這個(gè)命令接受行號(hào)或者函數(shù)名作為參數(shù): (gdb) break 10 在第 10行設(shè)置斷點(diǎn) Breakpoint 1 at 0x4004a7: file , line 10. (gdb) break summary 在 summary函數(shù)入口設(shè)置斷點(diǎn) Breakpoint 2 at 0x4004fb: file , line 22. 運(yùn)行程序和單步執(zhí)行 設(shè)置完斷點(diǎn)后,就可以運(yùn)行程序了。使用 run命令(縮寫(xiě)為 r)運(yùn)行程序至斷點(diǎn): (gdb) run 運(yùn)行程序 Starting program: /home/lewis/for_final/sum/ Breakpoint 1, main () at :10 10 for ( i = 1。 i = 100。 i++ ) { 監(jiān)視變量 調(diào)試程序最基本的手段就是監(jiān)視變量的值??梢允褂胮rint命令(縮寫(xiě)為 p)要求 gdb提供指定變量的值: (gdb) print sum 打印變量 sum的值 $1 = 6 (gdb) n 單步執(zhí)行 25 for ( i = 1。 i = n。 i++ ) { (gdb) 重復(fù)上一條命令(單步執(zhí)行) 26 sum += i。 (gdb) print sum 打印 sum的值 $2 = 10 臨時(shí)修改變量 gdb允許用戶在程序運(yùn)行時(shí)改變變量的值。通過(guò)set var命令實(shí)現(xiàn)這一點(diǎn): (gdb) print i $4 = 2 (gdb) set var i=1 (gdb) print i 查看堆棧情況 每次程序調(diào)用一個(gè)函數(shù),函數(shù)的地址、參數(shù)、函數(shù)內(nèi)的局部變量都會(huì)被壓入“?!保?Stack)中。運(yùn)行時(shí)堆棧的信息對(duì)于程序員非常重要。使用 bt命令可以看到當(dāng)前運(yùn)行時(shí)棧的情況: (gdb) bt 0 summary (n=450) at :22 1 0x00000000004004dc in main () at :15 退出 gdb 調(diào)試完畢,使用 quit命令(縮寫(xiě)為 q)退出 gdb程序: (gdb) c Continuing. Summary[1450] = 101475 Program exited normally. (gdb) quit 退出 gdb $ Shell提示符 如果程序還沒(méi)有運(yùn)行完畢,那么 gdb會(huì)要求用戶確認(rèn)退出命令。回答“ y”退出 gdb;回答“ n”回到調(diào)試環(huán)境: (gdb) quit The program is running. Exit anyway? (y or n) 命令匯總 本節(jié)只介紹了 gdb命令中很小的一部分(考慮一下 GDB標(biāo)準(zhǔn)文檔 《 Debugging with GDB》 346頁(yè)的篇幅)。 GDB命令 縮寫(xiě) 描述 help h 獲取幫助信息 list l 顯示源代碼 search 向前(朝向文件尾)搜索源代碼 reversesearch 向后(朝向文件頭)搜索源代碼 break b 設(shè)置斷點(diǎn) info break 查看斷點(diǎn)信息 clear 清除當(dāng)前所在行的斷點(diǎn) run r 從頭運(yùn)行程序至第一個(gè)斷點(diǎn) next n 單步執(zhí)行(不進(jìn)入函數(shù)體) step s 單步執(zhí)行(進(jìn)入函數(shù)體) continue c 從當(dāng)前行繼續(xù)運(yùn)行程序至下一個(gè)斷點(diǎn) print p 打印變量的值 watch 設(shè)置觀察點(diǎn) set var variable=value 設(shè)置變量 variable的值為 value bt 查看運(yùn)行時(shí)棧 quit q 退出 gdb 與他人協(xié)作:版本控制系統(tǒng) 生活中難免會(huì)出錯(cuò),保證所作的改動(dòng)能夠正確撤銷非常重要。在大型軟件開(kāi)發(fā)中,溝通不暢很有可能導(dǎo)致團(tuán)隊(duì)成員實(shí)施了彼此矛盾的修改,如果源代碼只是簡(jiǎn)單地處在一個(gè)目錄中,那么事情將變得一團(tuán)糟。幸運(yùn)的是,本節(jié)介紹的版本控制可以有效地解決這些問(wèn)題。在正式開(kāi)始之前,首先看一下版本控制系統(tǒng)到底能做些什么。 什么是版本控制 簡(jiǎn)單地說(shuō),版本控制系統(tǒng)是一套在開(kāi)發(fā)程序時(shí)存儲(chǔ)源代碼所有修改的工具。聽(tīng)起來(lái)這沒(méi)有什么特別的, cp命令就可以做到。的確,在每次完成源代碼的修改后,把先前的版本改名,再保存新的版本,這樣就完成了版本控制的最基本的功能。不過(guò)對(duì)于復(fù)雜性和健壯性要求更高的環(huán)境而言,開(kāi)發(fā)人員還有以下這些需求: 集中化管理,自動(dòng)跟蹤單個(gè)文件的修改歷史; 完善的日志機(jī)制,便于掌握某次修改的原因; 快速還原到指定的版本; 協(xié)調(diào)不同開(kāi)發(fā)者之間的活動(dòng),保證對(duì)源代碼同一部分的改動(dòng)不會(huì)互相覆蓋; 安裝 Subversion Subversion已經(jīng)包含在很多 Linux發(fā)行版中了,Ubuntu就在其安裝源中提供了 Subversion的下載。如果讀者使用的 Linux發(fā)行版沒(méi)有包含這個(gè)軟件,那么可以從 。使用源代碼還是二進(jìn)制安裝包完全取決于實(shí)際需求。 建立項(xiàng)目倉(cāng)庫(kù) “項(xiàng)目倉(cāng)庫(kù)”是版本控制系統(tǒng)的專有名詞,是用來(lái)存儲(chǔ)各種文件的主要場(chǎng)所。項(xiàng)目倉(cāng)庫(kù)以目錄作為載體,下面的命令建立目錄 svn_ex,本節(jié)所有的源代碼最終都會(huì)存放在里面: $ mkdir /home/lewis/svn_ex 接下來(lái)調(diào)用 svnadmin create命令建立項(xiàng)目倉(cāng)庫(kù): $ svnadmin create /home/lewis/svn_ex 如果沒(méi)有報(bào)錯(cuò),那么這個(gè)項(xiàng)目倉(cāng)庫(kù)就建好了。此時(shí) Subversion已經(jīng)在 svn_ex目錄中安放了一些東西, Subversion需要它們來(lái)記錄項(xiàng)目的一切。這是一套復(fù)雜的機(jī)制,普通用戶通常并不需要了解這些。 創(chuàng)建項(xiàng)目并導(dǎo)入源代碼 接下來(lái)就要著手建立一個(gè)新的項(xiàng)目。簡(jiǎn)便起見(jiàn),這里將本章已經(jīng)出現(xiàn)過(guò)的兩個(gè)源代碼文件導(dǎo)入項(xiàng)目倉(cāng)庫(kù): 進(jìn)入源程序所在的目錄 $ cd /home/lewis/sum/ 導(dǎo)入源程序,并創(chuàng)建項(xiàng)目 project $ svn import m 導(dǎo)入源文件至項(xiàng)目倉(cāng)庫(kù) . 增加 增加 開(kāi)始項(xiàng)目開(kāi)發(fā) 開(kāi)發(fā)人員總是在自己的機(jī)器上建立一個(gè)目錄,然后在這個(gè)目錄中編寫(xiě)程序。下面的命令在用戶主目錄中建立 work/project目錄,接下來(lái)的“開(kāi)發(fā)”就將在這里面進(jìn)行: $ mkdir ~/work $ cd ~/work/ $ mkdir project 修改代碼和提交改動(dòng) 現(xiàn)在 lewis決定修改 “錯(cuò)誤”,他把源代碼的第一行改成下面這個(gè)樣子: define S