linux環(huán)境程序設(shè)計(jì)教學(xué)-第3章_第1頁(yè)
linux環(huán)境程序設(shè)計(jì)教學(xué)-第3章_第2頁(yè)
linux環(huán)境程序設(shè)計(jì)教學(xué)-第3章_第3頁(yè)
linux環(huán)境程序設(shè)計(jì)教學(xué)-第3章_第4頁(yè)
linux環(huán)境程序設(shè)計(jì)教學(xué)-第3章_第5頁(yè)
已閱讀5頁(yè),還剩23頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第3章LinuxGCC/G++編譯器與調(diào)試器編譯器是將易于編寫、閱讀和維護(hù)的高級(jí)計(jì)算機(jī)語(yǔ)言翻譯為計(jì)算機(jī)能解讀、運(yùn)行的低級(jí)機(jī)器語(yǔ)言的程序。調(diào)試器是用于查找源代碼中的錯(cuò)誤,測(cè)試源代碼和可執(zhí)行文件的工具。GNU項(xiàng)目提供了GCC編譯器、G++編譯器和GDB調(diào)試器,這些程序是在Linux系統(tǒng)上使用C和C++語(yǔ)言進(jìn)行開(kāi)發(fā)的重要工具。本章將介紹這些工具的安裝和使用方法。3.1GCC/G++編譯器GCC是GNU項(xiàng)目中的一個(gè)子項(xiàng)目,最初為用于編譯C語(yǔ)言的編譯器。隨著GNU項(xiàng)目的發(fā)展,GCC已經(jīng)成為了能編譯C、C++、Ada、ObjectC和Java等語(yǔ)言的GNU編譯器家族,同時(shí)還可執(zhí)行跨硬件平臺(tái)的交叉編譯工作。G++則是專門用來(lái)編寫C和C++語(yǔ)言的編譯器。C和C++語(yǔ)言正在不斷發(fā)展,為了保持兼容程序語(yǔ)言的最新特性,開(kāi)發(fā)者通常選擇GCC來(lái)編譯C語(yǔ)言編寫的源代碼,選擇G++來(lái)編譯C++源代碼。3.1.1GCC/G++編譯器安裝安裝或更新GCC和G++可在GNU項(xiàng)目的官方網(wǎng)站()去下載相應(yīng)的安裝包,也可以使用YUM軟件包管理器安裝。安裝GCC和G++的命令如下:yuminstallmake //安裝make程序yuminstallgcc //安裝GCC編譯器yuminstallgcc-c++ //安裝G++編譯器注意:如果安裝過(guò)程中提示需要選擇編譯器版本,可根據(jù)當(dāng)前硬件平臺(tái)選擇最新發(fā)布的版本。另外,如果提示需要安裝其它相關(guān)軟件包,請(qǐng)一并安裝。3.1.2GCC/G++編譯命令GCC/G++編譯器沒(méi)有圖形界面,只能在終端上以命令方式運(yùn)行。編譯命令由命令名、選項(xiàng)和源文件名組成,格式如下:gcc[-選項(xiàng)1][-選項(xiàng)2]…[-選項(xiàng)n]<源文件名>g++[-選項(xiàng)1][-選項(xiàng)2]…[-選項(xiàng)n]<源文件名>命令名、選項(xiàng)和源文件名之間使用空格分隔,一行命令中可以有多個(gè)選項(xiàng),也可以只有一個(gè)選項(xiàng)。文件名可以包含文件的絕對(duì)路徑,也可以使用相對(duì)路徑。如果文件名中不包含路徑,那么源文件被視為存在于工作目錄中。如果命令中不包含輸出的可執(zhí)行文件名稱,默認(rèn)情況下將在工作目錄中生成后綴為“.out”的可執(zhí)行文件。3.1.3GCC/G++編譯選項(xiàng)GCC擁有一百多個(gè)編譯選項(xiàng)。對(duì)于C語(yǔ)言和C++語(yǔ)言,G++與GCC的編譯選項(xiàng)基本相同。常用的GCC和G++編譯選項(xiàng)如表所示。3.1.3GCC/G++編譯選項(xiàng)編譯選項(xiàng)說(shuō)

明-c只進(jìn)行預(yù)處理、編譯和匯編,生成“.o”文件-S只進(jìn)行預(yù)處理和編譯,生成“.s”文件-E只進(jìn)行預(yù)處理,產(chǎn)生預(yù)處理后的結(jié)果到標(biāo)準(zhǔn)輸出-C預(yù)處理時(shí)不刪除注釋信息,常與-E同時(shí)使用-o指定目標(biāo)名稱,常與-c、-S同時(shí)使用,默認(rèn)是“.out”-includefile插入一個(gè)文件,功能等同源代碼中的#include-Dmacro[=defval]定義一個(gè)宏,功能等同源代碼中的#definemacro[defval]-Umacro取消宏的定義,功能等同源代碼中的#undefmacro-Idir優(yōu)先在選項(xiàng)后的目錄中查找包含的頭文件-lname鏈接后綴為“.so”的動(dòng)態(tài)鏈接庫(kù)來(lái)編譯程序-Ldir指定編譯搜索庫(kù)的路徑-O[0-3]編譯器優(yōu)化,數(shù)值越大優(yōu)化級(jí)別越高,0沒(méi)有優(yōu)化-g編譯器編譯時(shí)加入debug信息-pg編譯器加入信息給gprof-share使用動(dòng)態(tài)庫(kù)-static禁止使用動(dòng)態(tài)庫(kù)3.1.4GCC/G++編譯器執(zhí)行過(guò)程GCC和G++編譯器執(zhí)行過(guò)程可總結(jié)為4步:預(yù)處理、編譯、匯編、連接。在預(yù)處理過(guò)程中,編譯器會(huì)對(duì)源代碼中的頭文件和預(yù)處理語(yǔ)句進(jìn)行分析,生成以“.i”為后綴的預(yù)處理文件。編譯過(guò)程是將輸入的源代碼編譯為以“.o”為后綴的目標(biāo)文件。匯編過(guò)程是針對(duì)匯編語(yǔ)言的步驟,編譯后生成以“.o”為后綴的目標(biāo)文件。最后執(zhí)行連接過(guò)程,所有的目標(biāo)文件被安排在可執(zhí)行程序中恰當(dāng)?shù)奈恢?。同時(shí),該程序所調(diào)用到的庫(kù)函數(shù)也從各自所在的檔案庫(kù)中連到合適的地方,如圖所示。3.2程序和進(jìn)程程序和進(jìn)程是操作系統(tǒng)中的重要概念。程序是可運(yùn)行的一組指令,以二進(jìn)制代碼的形式保存在存儲(chǔ)設(shè)備中。操作系統(tǒng)運(yùn)行程序后,該程序在內(nèi)存中的映像就是進(jìn)程,進(jìn)程是活動(dòng)的程序。3.2.1程序程序是指一組指示計(jì)算機(jī)或其它具有信息處理能力設(shè)備每一步動(dòng)作的指令。Linux系統(tǒng)下的應(yīng)用程序主要由兩種特殊類型的文件代表,分別是可執(zhí)行文件和腳本程序。可執(zhí)行文件是能夠被計(jì)算機(jī)直接執(zhí)行的程序,相當(dāng)于Windows系統(tǒng)中的exe文件。使用C和C++語(yǔ)言設(shè)計(jì)的程序編譯后即是可執(zhí)行文件。Linux系統(tǒng)不要求可執(zhí)行文件使用特定的擴(kuò)展名,文件是否能被執(zhí)行由文件的系統(tǒng)屬性來(lái)決定。3.2.2進(jìn)程和PID進(jìn)程是一個(gè)具有獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次可以并發(fā)執(zhí)行的運(yùn)行活動(dòng),是處于活動(dòng)狀態(tài)的程序。進(jìn)程作為構(gòu)成系統(tǒng)的基本元件,不僅是系統(tǒng)內(nèi)部獨(dú)立運(yùn)行的實(shí)體,而且是獨(dú)立競(jìng)爭(zhēng)資源的實(shí)體。在Linux系統(tǒng)中,用戶創(chuàng)建進(jìn)程時(shí)會(huì)先在系統(tǒng)的進(jìn)程表中為進(jìn)程創(chuàng)建獨(dú)一無(wú)二的編碼,即PID。PID是一個(gè)正整數(shù),取值范圍在2到32768之間。進(jìn)程創(chuàng)建時(shí)會(huì)順序挑選下一個(gè)未使用的編號(hào)數(shù)字作為自己的PID,如果它們已經(jīng)經(jīng)過(guò)一圈的循環(huán),新的編碼重新從2開(kāi)始。數(shù)字1一般是為特殊進(jìn)程init保留的,它負(fù)責(zé)管理其它的進(jìn)程。例如,執(zhí)行下列命令顯示系統(tǒng)內(nèi)的所有進(jìn)程。ps-e3.3ANSIC標(biāo)準(zhǔn)C語(yǔ)言誕生后的很長(zhǎng)一段時(shí)期內(nèi),并沒(méi)有針對(duì)C語(yǔ)言制定嚴(yán)格的標(biāo)準(zhǔn)。不同編譯器可能使用不同的語(yǔ)法規(guī)則或數(shù)據(jù)結(jié)構(gòu),此狀況對(duì)程序的移植帶來(lái)很多麻煩。于是,美國(guó)國(guó)家標(biāo)準(zhǔn)協(xié)會(huì)(ANSI)決定統(tǒng)一C語(yǔ)言的標(biāo)準(zhǔn),并于1989年頒布《ANSX3.159-1989》標(biāo)準(zhǔn)文檔,這一標(biāo)準(zhǔn)被稱為ANSIC標(biāo)準(zhǔn)。ANSIC標(biāo)準(zhǔn)在訂立時(shí)吸取了很多C++語(yǔ)言的內(nèi)容,同時(shí)促使C語(yǔ)言支持多國(guó)字符集,其中包括各種中文字符集。ANSIC標(biāo)準(zhǔn)的推出使C語(yǔ)言保持著活力,成為最受開(kāi)發(fā)者歡迎的開(kāi)發(fā)語(yǔ)言。1999年,ANSI推出了C語(yǔ)言標(biāo)準(zhǔn)的修訂版,該修訂版簡(jiǎn)稱C99。GCC編譯器均和GDB調(diào)試器以ANSIC標(biāo)準(zhǔn)為原則,同時(shí)也支持C99。3.3.1函數(shù)原型C語(yǔ)言設(shè)計(jì)的程序是由函數(shù)所組成的,在函數(shù)被詳細(xì)定義前,可先在頭文件定義函數(shù)原型,這樣函數(shù)間可更容易地相互調(diào)用。頭文件<unistd.h>包含了許多Linux系統(tǒng)服務(wù)的函數(shù)原型,例如read()、write()和getpid()函數(shù),它們的原型如下:ssize_tread(int,void*,size_t);

//read()函數(shù)的原型ssize_twrite(int,constvoid*,size_t);//write()函數(shù)的原型pid_tgetpid(void);

//getpid()函數(shù)的原型函數(shù)原型由函數(shù)的返回類型、函數(shù)名和參數(shù)3部分組成。例如第一行中ssize_t表示該函數(shù)返回值是ssize_t類型的值。括號(hào)中是參數(shù)列表,多個(gè)參數(shù)用逗號(hào)分隔,代碼中最后一行g(shù)etpid()函數(shù)的參數(shù)是void,表示getpid()函數(shù)沒(méi)有參數(shù)。當(dāng)源代碼編譯時(shí),因?yàn)榫幾g器已經(jīng)知道參數(shù)的類型,所以會(huì)將調(diào)用的參數(shù)進(jìn)行強(qiáng)制轉(zhuǎn)換。3.3.2類屬指針類屬指針是一種能夠同時(shí)支持所有數(shù)據(jù)類型的指針,函數(shù)原型中常用的“void*”類型即是類屬指針。ANSIC標(biāo)準(zhǔn)常用類屬指針代替函數(shù)參數(shù)中的其它指針,使同一個(gè)函數(shù)能支持多種數(shù)據(jù)類型。相關(guān)內(nèi)容將在本書的程序?qū)嵗卸啻我?jiàn)到。3.3.3原始系統(tǒng)數(shù)據(jù)類型在函數(shù)原型中以“_t”結(jié)尾的類型被稱為原始系統(tǒng)數(shù)據(jù)類型。原始系統(tǒng)數(shù)據(jù)類型定義在頭文件sys/types.h中,以typedef操作符加以定義。原始系統(tǒng)數(shù)據(jù)類型是目標(biāo)系統(tǒng)數(shù)據(jù)結(jié)構(gòu)的接口,在不同的操作系統(tǒng)中,其字長(zhǎng)會(huì)有變化。3.4編譯helloworldhelloworld程序作為程序員學(xué)習(xí)的第一個(gè)程序已成為有趣的慣例。本節(jié)將講述如何使用Linux系統(tǒng)中默認(rèn)的編譯器編輯該程序的源代碼,并使用GCC編譯器將該程序編譯為可執(zhí)行文件。3.4.1使用VI編寫源代碼VI是Linux系統(tǒng)中最常用的文本編輯器,幾乎所有Linux發(fā)行版中都已包含VI程序。它工作在控制臺(tái)或終端中,通過(guò)shell調(diào)用,全部操作均由命令完成,對(duì)于初學(xué)者來(lái)說(shuō)并不容易掌握。下例命令在用戶主目錄“/home/用戶名”中創(chuàng)建一個(gè)名為helloworld的目錄,并在該目錄中使用VI新建并打開(kāi)helloworld.c文件。cd~

//進(jìn)入“/home/用戶名”目錄,使之成為工作目錄mkdirhelloworld

//新建helloworld目錄cdhelloworld

//進(jìn)入helloworld目錄,工作目錄是“/home/用戶名/helloworld”vihelloworld.c

//使用vi新建并打開(kāi)helloworld.c文件3.4.1使用VI編寫源代碼“.c”結(jié)尾的文件表示該文件是C語(yǔ)言源代碼。執(zhí)行完以上命令,終端即進(jìn)入VI程序。這時(shí)先按下Esc鍵進(jìn)入命令輸入狀態(tài),再輸入命令a并按下Enter鍵,VI可從光標(biāo)所在位置開(kāi)始錄入文本。輸入helloworld.c文件的內(nèi)容:01

#include<stdio.h>

//這個(gè)頭文件包含基本的輸入輸出函數(shù)02

intmain()

//主函數(shù),程序?qū)倪@里開(kāi)始執(zhí)行03

{04

char*c; //聲明一個(gè)字符串變量c05

c="helloworld!";

//為字符串變量賦值06

printf("%s\n",c);

//輸出該變量,并輸出換行符07

return0;

//程序結(jié)束時(shí)向操作系統(tǒng)返回0,表示正常退出08

}錄入結(jié)束后,先按下Esc退出輸入狀態(tài),再輸入命令Q進(jìn)入Ex模式,在Ex模式下輸入wq并按下Enter鍵,該文件被保存并退出VI程序。VI的命令非常豐富,如果輸入有誤或需修改文件,可參照后表對(duì)文本進(jìn)行修改。3.4.1使用VI編寫源代碼命

令解

釋命

令解

釋Esc進(jìn)入或退出命令模式i/I插入h/j/k/l或方向鍵移動(dòng)光標(biāo)位置a/A在光標(biāo)后輸入/關(guān)鍵字向下查找關(guān)鍵字o/O插入新行x/X向前,向后刪除一個(gè)字符r/R在光標(biāo)后改寫D/d刪除整行w保存文件Y/y復(fù)制整行q退出VIp/P在上一行,下一行粘貼wq保存文件并退出U還原前一動(dòng)作setnu顯示行號(hào)3.4.2程序的編譯與連接程序經(jīng)過(guò)編譯器的編譯與連接后,即可生成可執(zhí)行文件。如果源代碼有語(yǔ)法錯(cuò)誤,則會(huì)在終端上顯示錯(cuò)誤信息。有些時(shí)候,編譯器會(huì)出現(xiàn)警告提示,但程序依然被編譯成功。這表明源代碼沒(méi)有嚴(yán)格按照標(biāo)準(zhǔn)編寫,可能會(huì)在運(yùn)行時(shí)出現(xiàn)意外的結(jié)果。繼續(xù)前面的操作不改變工作目錄,編譯并連接helloworld.c程序,可在終端上輸入下列命令:gcc-ohelloworld

helloworld.c

//編譯并連接程序//-ohelloworld表示使用helloworld作為目標(biāo)文件名3.4.3使用終端運(yùn)行程序要運(yùn)行helloworld程序,繼續(xù)前面的操作不改變工作目錄,只需要在終端上輸入下列命令:./helloworld

//運(yùn)行當(dāng)前目錄下的helloworld程序程序的輸出結(jié)果為:helloworld!Linux系統(tǒng)上運(yùn)行程序,必須給出該程序完整的路徑。前面的helloworld.c文件建立在“/home/用戶名/helloworld”目錄中,編譯和連接后所生成的可執(zhí)行文件也在該目錄中。運(yùn)行程序則需輸入“/home/用戶名/helloworld/helloworld”。但當(dāng)前的工作目錄已經(jīng)是“/home/用戶名/helloworld”了,所以可用“./”替代工作目錄的路徑。3.5GDB調(diào)試器程序編寫后難免會(huì)出現(xiàn)各種錯(cuò)誤,當(dāng)程序完成編譯時(shí),隱藏的錯(cuò)誤可能會(huì)使程序無(wú)法正常運(yùn)行,或者不能實(shí)現(xiàn)預(yù)期的功能。簡(jiǎn)單的程序或淺顯的錯(cuò)誤可依賴程序員的經(jīng)驗(yàn)判斷出故障點(diǎn),但現(xiàn)在的軟件規(guī)格越來(lái)越大,調(diào)試起來(lái)也就越來(lái)越困難。調(diào)試器是幫助程序員修改錯(cuò)誤的得力工具,常用的斷點(diǎn)、單步跟蹤等功能可快速找到故障點(diǎn)。3.5.1GDB調(diào)試器概述Linux程序員中最常用的調(diào)試工具是GDB,GDB調(diào)試器是GNU項(xiàng)目的子項(xiàng)目。該程序提供了所有常用調(diào)試功能,是Linux系統(tǒng)中最為簡(jiǎn)單快捷的調(diào)試工具。由于當(dāng)前圖形用戶界面(GUI)普及,大量基于GUI的調(diào)試器被開(kāi)發(fā)和運(yùn)行在Linux上。它們大多是以GDB為核心配上GUI:用戶通過(guò)GUI發(fā)出命令,這些命令依次被傳送給GDB。其中一個(gè)是DDD,意為數(shù)據(jù)顯示調(diào)試器。在一些集成開(kāi)發(fā)環(huán)境如Eclipse中,也提供了調(diào)試功能,并且以GDB為核心。3.5.2GDB調(diào)試器安裝通常在Linux桌面版的軟件開(kāi)發(fā)包集合中已包含GDB調(diào)試器。如果需要安裝或更新GDB調(diào)試器,可使用YUM軟件包管理器完成,操作方法如下:yuminstallgdb //YUM安裝GDB調(diào)試器3.5.3GDB常用調(diào)試命令GDB調(diào)試器調(diào)試的對(duì)象是可執(zhí)行文件,使用GCC或G++編譯器編譯源代碼時(shí),必須加上選項(xiàng)-g才能使目標(biāo)可執(zhí)行文件包含可被調(diào)試的信息。以3.4節(jié)中helloworld程序?yàn)槔?,編譯連接程序,并使用GDB調(diào)試器打開(kāi)目標(biāo)可執(zhí)行文件的命令如下:gcc-g-ohelloworld

helloworld.c

//編譯并連接程序,使之包含可被調(diào)試信息gdbhelloworld

//使用GDB調(diào)試器打開(kāi)helloworld可執(zhí)行文件完成以上操作后,系統(tǒng)將顯示GDB調(diào)試器的版本、使用的函數(shù)庫(kù)信息,并顯示(gdb)命令提示符。這時(shí)可輸入命令對(duì)程序進(jìn)行調(diào)試,常用的命令見(jiàn)后表。3.5.3GDB常用調(diào)試命令命

令解

釋file<文件名>在GDB中打開(kāi)執(zhí)行文件break設(shè)置斷點(diǎn),支持如下形式:break行號(hào)、break函數(shù)名稱、break行號(hào)/函數(shù)名稱if條件info查看和可執(zhí)行程序相關(guān)的各種信息kill終止正在調(diào)試的程序print顯示變量或表達(dá)式的值setargs設(shè)置調(diào)試程序的運(yùn)行參數(shù)delete刪除設(shè)置的某個(gè)斷點(diǎn)或觀測(cè)點(diǎn),與break操作相似clear刪除設(shè)置在指定行號(hào)或函數(shù)上的斷點(diǎn)continue從斷點(diǎn)處繼續(xù)執(zhí)行程序list列出GDB中打開(kāi)的可執(zhí)行文件代碼watch在程序中設(shè)置觀測(cè)點(diǎn)run運(yùn)行打開(kāi)的可執(zhí)行文件next單步執(zhí)行程序step進(jìn)入所調(diào)用的函數(shù)內(nèi)部,查看執(zhí)行情況whatis查看變量或函數(shù)類型,調(diào)用格式為“whatis變量名/函數(shù)名”ptype顯示數(shù)據(jù)結(jié)構(gòu)定義情況make編譯程序quit退出GDB3.5.4在GDB下運(yùn)行程序打開(kāi)可執(zhí)行文件后,可根據(jù)需要在程序中加入斷點(diǎn)或觀察點(diǎn),并運(yùn)行程序。以helloworld程序?yàn)槔?,可在為變量賦值前加入斷點(diǎn),并運(yùn)行程序。繼續(xù)3.5.3小節(jié)的操作,方法如下:(gdb)break5

//在源代碼第5行,即變量c賦值處加入斷點(diǎn)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論