Linux課件 2-4Linux編程基礎(chǔ)_第1頁
Linux課件 2-4Linux編程基礎(chǔ)_第2頁
Linux課件 2-4Linux編程基礎(chǔ)_第3頁
Linux課件 2-4Linux編程基礎(chǔ)_第4頁
Linux課件 2-4Linux編程基礎(chǔ)_第5頁
已閱讀5頁,還剩52頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、linux編程基礎(chǔ),Linux程序設(shè)計基礎(chǔ),本章學(xué)習(xí)目標(biāo) 通過對本章的學(xué)習(xí),讀者應(yīng)該掌握以下主要內(nèi)容: Linux編程風(fēng)格 Linux下使用GNU cc開發(fā)應(yīng)用程序 Linux程序的調(diào)試,1.概述,1.1 Linux編程 Linux軟件開發(fā)一直在Internet環(huán)境下講行。這個環(huán)境是全球性的,編程人員來自世界各地。只要能夠訪問Web站點,就可以啟動一個以Linux為基礎(chǔ)的軟件項目。Linux開發(fā)工作經(jīng)常是在Linux用戶決定共同完成一個項目時開始的。當(dāng)開發(fā)工作完成后,該軟件就被放到Internet站點上,任何用戶都可以訪問和下載它。由于這個活躍的開發(fā)環(huán)境,新的以Linux為基礎(chǔ)的軟件功能日益強

2、大,而且呈現(xiàn)爆炸式的增長態(tài)勢。,大多數(shù)Linux軟件是經(jīng)過自由軟件基金會(Free Software Foundation)提供的GNU(GNU 即 GNUs not UNIX)公開認(rèn)證授權(quán)的,因而通常被稱作GNU軟件。GNU軟件免費提供給用戶使用,并被證明是非??煽亢透咝У?。許多流行的Linux實用程序如C編譯器、shell和編輯器都是GNU軟件應(yīng)用程序。,Linux程序需要首先轉(zhuǎn)化為低級機器語言即所謂的二進制代碼以后,才能被操作系統(tǒng)執(zhí)行。例如編程時,先用普通的編程語言生成一系列指令,這些指令可被翻譯為適當(dāng)?shù)目蓤?zhí)行應(yīng)用程序的二進制代碼。這個翻譯過程可由解釋器一步步來完成,或者也可以立即由編譯

3、器明確地完成。shell編程語言如BASH、TCSH、GAWK、Perl、Tcl和Tk都利用自己的解釋器。用這些語言編制的程序盡管是應(yīng)用程序文件,但可以直接運行。編譯器則不同,它將生成一個獨立的二進制代碼文件然后才可以運行。,1GNU風(fēng)格 (1)函數(shù)返回類型說明和函數(shù)名分兩行放置,函數(shù)起始字符和函數(shù)開頭左花括號放到最左邊。 (2)盡量不要讓兩個不同優(yōu)先級的操作符出現(xiàn)在相同的對齊方式中,應(yīng)該附加額外的括號使得代碼縮進可以表示出嵌套。 (3)按照規(guī)定方式排版do-while語句: (4)每個程序都應(yīng)該以一段簡短的說明其功能的注釋開頭。 (5)請為每個函數(shù)書寫注釋,說明函數(shù)是做什么的,需要哪些入口參

4、數(shù),參數(shù)可能值的含義和用途。如果用了非常見的、非標(biāo)準(zhǔn)的東西,或者可能導(dǎo)致函數(shù)不能工作的任何可能的值,應(yīng)該進行特殊說明。如果存在重要的返回值,也需要說明。,(6)不要聲明多個變量時跨行,每一行都以一個新的聲明開頭。 (7)當(dāng)一個if中嵌套了另一個if-else時,應(yīng)用花括號把if-else括起來。 (8)要在同一個聲明中同時說明結(jié)構(gòu)標(biāo)識和變量或者結(jié)構(gòu)標(biāo)識和類型定義(typedef)。先定義變量,再使用。 (9)盡量避免在if的條件中進行賦值。 (10)請在名字中使用下劃線以分割單詞,盡量使用小寫;把大寫字母留給宏和枚舉常量,以及根據(jù)統(tǒng)一慣例使用的前綴。例如,應(yīng)該使用類似ignore_space_

5、change_flag的名字;不要使用類似iCantReadThis的名字。,2Linux 內(nèi)核編程風(fēng)格 (1)Linux內(nèi)核縮進風(fēng)格是8個字符。 (2)Linux內(nèi)核風(fēng)格采用K&R標(biāo)準(zhǔn),將開始的大括號放在一行的最后,而將結(jié)束的大括號放在一行的第一位。 (3)命名盡量簡潔。不應(yīng)該使用諸如ThisVariableIsATemporaryCounter之類的名字。應(yīng)該命名為tmp,這樣容易書寫,也不難理解。但是命名全局變量,就應(yīng)該用描述性命名方式,例如應(yīng)該命名“count_active_users()”,而不是“cntusr()”。本地變量應(yīng)該避免過長。,2. Vi 的使用,vi提供了一些功能強大

6、的但容易記憶的命令供用戶使用。類似這樣的編輯任務(wù)在vi中可以輕松高效完成。,編輯命令,光標(biāo)命令,文件命令,狀態(tài)命令,3. 使用GNU cc開發(fā)應(yīng)用程序,3.1 使用GNU cc gcc可以使程序員靈活地控制編譯過程。編譯過程一般可以分為下面四個階段,每個階段分別調(diào)用不同的工具進行處理,如圖9-18所示。,3.2 gcc的版本信息 一般來說,系統(tǒng)安裝后就已經(jīng)安裝和設(shè)定好了gcc。在shell的提示符下鍵入gcc v,屏幕上就會顯示出目前正在使用的gcc的版本,同時這可以確定系統(tǒng)所支持的是ELF還是a.out可執(zhí)行文件格式。,Linux系統(tǒng)中可執(zhí)行文件有兩種格式。第一種格式是a.out格式,這種格

7、式用于早期的Linux系統(tǒng)以及 Unix系統(tǒng)的原始格式。a.out來自于Unix C編譯程序默認(rèn)的可執(zhí)行文件名。當(dāng)使用共享庫時,a.out格式就會發(fā)生問題。把a.out格式調(diào)整為共享庫是一種非常復(fù)雜的操作,由于這個原因,一種新的文件格式被引入Unix系統(tǒng)5的第四版本和Solaris系統(tǒng)中。它被稱為可執(zhí)行和連接的格式(ELF)。這種格式很容易實現(xiàn)共享庫。,ELF格式已經(jīng)被Linux系統(tǒng)作為標(biāo)準(zhǔn)的格式采用。gcc編譯程序產(chǎn)生的所有的二進制文件都是ELF格式的文件(即使可執(zhí)行文件的默認(rèn)名仍然是a.out)。較舊的a.out格式的程序仍然可以運行在支持ELF格式的系統(tǒng)上。,3.3 gcc的使用,gcc

8、的使用格式如下: $ gcc optionsfilenames 其中filenames為所要編譯的程序源文件。 當(dāng)使用gcc時,gcc會完成預(yù)處理、編譯、匯編和連接。前三步分別生成目標(biāo)文件,連接時,把生成的目標(biāo)文件鏈接成可執(zhí)行文件。gcc可以針對支持不同的源程序文件進行不同處理,文件格式以文件的后綴來識別。,3.4 使用優(yōu)化選項,當(dāng)用gcc編譯C代碼時,它會試著用最少的時間完成編譯并且使編譯后的代碼易于調(diào)試. 易于調(diào)試意味著編譯后的代碼與源代碼有同樣的執(zhí)行次序,編譯后的代碼沒有經(jīng)過優(yōu)化。有很多選項可用于告訴gcc,在耗費更多編譯時間和犧牲易調(diào)試性的基礎(chǔ)上,產(chǎn)生更小更快的可執(zhí)行文件。這些選項中最

9、典型的是-O和-O2選項。,-O選項告訴gcc對源代碼進行基本優(yōu)化。這些優(yōu)化在大多數(shù)情況下都會使程序執(zhí)行的更快。 -O2選項告訴gcc產(chǎn)生盡可能小和盡可能快的代碼。-O2選項將使編譯的速度比使用-O 時慢。但通常產(chǎn)生的代碼執(zhí)行速度會更快。,3.5 使用調(diào)試和剖析選項,GCC 支持?jǐn)?shù)種調(diào)試和剖析選項。在這些選項里最常用的是-g和-pg選項。 -g選項告訴gcc產(chǎn)生能被GNU調(diào)試器使用的調(diào)試信息以便調(diào)試程序。gcc 提供了一個很多其他C編譯器里沒有的特性,在gcc里能使-g和-O(產(chǎn)生優(yōu)化代碼)連用。這一點非常有用,因為能在與最終產(chǎn)品盡可能相近的情況下調(diào)試代碼。同時使用這兩個選項時必須清楚所寫的某

10、些代碼已經(jīng)在優(yōu)化時被gcc作了改動。 -pg選項告訴gcc在程序里加入額外的代碼,執(zhí)行時,產(chǎn)生gprof用的剖析信息以顯示程序的耗時情況。,4. 使用GNU make編輯makefile,4.1 準(zhǔn)備工作 要使用make,必須編寫一個叫做Makefile的文件,這個文件描述了軟件包中文件之間的關(guān)系,提供更新每個文件的命令。一般在一個軟件包里,通常是可執(zhí)行文件靠目標(biāo)文件來更新,目標(biāo)文件靠編譯源文件來更新。,Makefile寫好之后,每次改變了某些源文件,只要執(zhí)行make命令: # make 所有必要的重新編譯將執(zhí)行。Make程序利用makefile中的數(shù)據(jù)和每個文件的最后修改時間來確定那個文件需

11、要更新,對于需要更新的文件,make程序執(zhí)行makefile數(shù)據(jù)中定義的命令來更新。,4.2 makefile文件的基本結(jié)構(gòu),GNU make的主要功能是讀進一個文本文件makefile并根據(jù)makefile的內(nèi)容執(zhí)行一系列的工作。makefile的默認(rèn)文件名為GNUmakefile、makefile或Makefile,當(dāng)然也可以在make的命令行中指定別的文件名。如果不特別指定,make命令在執(zhí)行時將按順序查找默認(rèn)的makefile文件。多數(shù)Linux程序員使用第三種文件名Makefile。因為第一個字母是大寫,通常被列在一個目錄的文件列表的最前面。,Makefile是一個文本形式的數(shù)據(jù)庫文

12、件,其中包含一些規(guī)則來告訴make處理哪些文件以及如何處理這些文件。這些規(guī)則主要是描述哪些文件(稱為target目標(biāo)文件,不要和編譯時產(chǎn)生的目標(biāo)文件相混淆)是從哪些別的文件(稱為dependency依賴文件)中產(chǎn)生的,以及用什么命令(command)來執(zhí)行這個過程。,依靠這些信息,make會對磁盤上的文件進行檢查,如果目標(biāo)文件的生成或被改動時的時間(稱為該文件時間戳)至少比它的一個依賴文件還舊的話,make就執(zhí)行相應(yīng)的命令,以更新目標(biāo)文件。目標(biāo)文件不一定是最后的可執(zhí)行文件,可以是任何一個中間文件并可以作為其他目標(biāo)文件的依賴文件。,一個Makefile文件主要含有一系列的規(guī)則,每條規(guī)則包含以下內(nèi)

13、容。 一個目標(biāo)(target),即make最終需要創(chuàng)建的文件,如可執(zhí)行文件和目標(biāo)文件;目標(biāo)也可以是要執(zhí)行的動作,如“clean”。 一個或多個依賴文件(dependency)列表,通常是編譯目標(biāo)文件所需要的其他文件。 一系列命今(command),是make執(zhí)行的動作,通常是把指定的相關(guān)文件編譯成目標(biāo)文件的編譯命令,每個命令占一行,且每個命令行的起始字符必須為TAB字符。,例如,有以下的Makefile文件: # 一個簡單的Makefile的例子 # 以#開頭的為注釋行 test:prog.o code.o gcc o test prog.o code.o prog.o:prog.c prog

14、.h code.h gcc c prog.c o prog.o code.o:code.c code.h gcc c code.c o code.o clean: rm f *.o,上面的Makefile文件中共定義了四個目標(biāo):test、prog.o、code.o和clean。目標(biāo)從每行的最左邊開始寫,后面跟一個冒號(:),如果有與這個目標(biāo)有依賴性的其他目標(biāo)或文件,把它們列在冒號后面,并以空格隔開。然后另起一行開始寫實現(xiàn)這個目標(biāo)的一組命令。在Makefile中,可使用續(xù)行號()將一個單獨的命令行延續(xù)成幾行。但要注意在續(xù)行號()后面不能跟任何字符(包括空格和鍵)。,一般情況下,調(diào)用make命令可

15、輸入: # make target target是Makefile文件中定義的目標(biāo)之一,如果省略target,make就將生成Makefile文件中定義的第一個目標(biāo)。對于上面Makefile的例子,單獨的一個“make”命令等價于: # make test 因為test是Makefile文件中定義的第一個目標(biāo),make首先將其讀入,然后從第一行開始執(zhí)行,把第一個目標(biāo)test作為它的最終目標(biāo),所有后面的目標(biāo)的更新都會影響到test的更新。第一條規(guī)則說明只要文件test的時間戳比文件prog.o或code.o中的任何一個舊,下一行的編譯命令將會被執(zhí)行。,但是,在檢查文件prog.o和code.o的

16、時間戳之前,make會在下面的行中尋找以prog.o和code.o為目標(biāo)的規(guī)則,在第三行中找到了關(guān)于prog.o的規(guī)則,該文件的依賴文件是prog.c、prog.h和code.h。同樣,make會在后面的規(guī)則行中繼續(xù)查找這些依賴文件的規(guī)則,如果找不到,則開始檢查這些依賴文件的時間戳,如果這些文件中任何一個的時間戳比prog.o的新,make將執(zhí)行“gcc c prog.c o prog.o”命令,更新prog.o文件。,以同樣的方法,接下來對文件code.o做類似的檢查,依賴文件是code.c和code.h。當(dāng)make執(zhí)行完所有這些套嵌的規(guī)則后,make將處理最頂層的test規(guī)則。如果關(guān)于pr

17、og.o和code.o的兩個規(guī)則中的任何一個被執(zhí)行,至少其中一個.o目標(biāo)文件就會比test新,那么就要執(zhí)行test規(guī)則中的命令,因此make去執(zhí)行g(shù)cc命令將prog.o和code.o連接成目標(biāo)文件test。 在上面Makefile的例子中,還定義了一個目標(biāo)clean,它是Makefile中常用的一種專用目標(biāo),即刪除所有的目標(biāo)模塊。,現(xiàn)在來看一下make做的工作:首先make按順序讀取makefile中的規(guī)則,然后檢查該規(guī)則中的依賴文件與目標(biāo)文件的時間戳哪個更新,如果目標(biāo)文件的時問戳比依賴文件還早,就按規(guī)則中定義的命令更新目標(biāo)文件。如果該規(guī)則中的依賴文件又是其他規(guī)則中的目標(biāo)文件,那么依照規(guī)則鏈

18、不斷執(zhí)行這個過程,直到Makefile文件的結(jié)束,至少可以找到一個不是規(guī)則生成的最終依賴文件,獲得此文件的時間戳,然后從下到上依照規(guī)則鏈執(zhí)行目標(biāo)文件的時間戳比此文件時間戳舊的規(guī)則,直到最頂層的規(guī)則。,通過以上的分析過程,可以看到make的優(yōu)點,因為.o目標(biāo)文件依賴.c源文件,源碼文件里一個簡單改變都會造成那個文件被重新編譯,并根據(jù)規(guī)則鏈依次由下到上執(zhí)行編譯過程,直到最終的可執(zhí)行文件被重新連接。例如,當(dāng)改變一個頭文件的時候,由于所有的依賴關(guān)系都在Makefile里,因此不再需要記住依賴此頭文件的所有源碼文件,make可以自動的重新編譯所有那些因依賴這個頭文件而改變了的源碼文件,如果需要,再進行重

19、新連接。,4.3 Makefile中的變量,Makefile里的變量就像一個環(huán)境變量。事實上,環(huán)境變量在make中也被解釋成make的變量。這些變量對大小寫敏感,一般使用大寫宇母。幾乎可以從任何地方引用定義的變量,變量的主要作用如下: 保存文件名列表。在前面的例子里,作為依賴文件的一些目標(biāo)文件名出現(xiàn)在可執(zhí)行文件的規(guī)則中,而在這個規(guī)則的命令行里同樣包含這些文件并傳遞給gcc做為命令參數(shù)。如果使用一個變量來保存所有的目標(biāo)文件名,則可以方便地加入新的目標(biāo)文件而且不易出錯。,保存可執(zhí)行命令名,如編譯器。在不同的Linux系統(tǒng)中存在著很多相似的編譯器系統(tǒng),這些系統(tǒng)在某些地方會有細(xì)微的差別,如果項目被用在

20、一個非gcc的系統(tǒng)里,則必須將所有出現(xiàn)編譯器名的地方改成用新的編譯器名。但是如果使用一個變量來代替編譯器名,那么只需要改變該變量的值。其他所有地方的命令名就都改變了。,保存編譯器的參數(shù)。在很多源代碼編譯時,gcc需要很長的參數(shù)選項,在很多情況下,所有的編譯命令使用一組相同的選項,如果把這組選項使用一個變量代表,那么可以把這個變量放在所有引用編譯器的地方。當(dāng)要改變選項的時候,只需改變一次這個變量的內(nèi)容即可。,Makefile中的變量是用一個文本串在Makefile中定義的,這個文本串就是變量的值。只要在一行的開始寫下這個變量的名字,后面跟一個“”號,以及要設(shè)定這個變量的值即可定義變量,下面是定義

21、變量的語法: VARNAME=string 使用時,把變量用括號括起來,并在前面加上$符號,就可以引用變量的值: $VARNAME,make解釋規(guī)則時,VARNAME在等式右端展開為定義它的字符串。變量一般都在Makefile的頭部定義。按照慣例,所有的Makefile變量都應(yīng)該是大寫。如果變量的值發(fā)生變化,就只需要在一個地方修改,從而簡化了Makefile的維護。,現(xiàn)在利用變量把前面的Makefile重寫一遍: OBJS=prog.o code.o CC=gcc test:$ OBJS $ CC o test $ OBJS prog.o:prog.c prog.h code.h $ CC c

22、 prog.c o prog.o code.o:code.c code.h $ CC c code.c o code.o clean: rm f *.o,如:源程序為,經(jīng)過變量替換過后的makefile文件:,除用戶自定義的變量外,make還允許使用環(huán)境變量、自動變量和預(yù)定義變量。使用環(huán)境變量的方法很簡單,在make啟動時,make讀取系統(tǒng)當(dāng)前已定義的環(huán)境變量,并且創(chuàng)建與之同名同值的變量,因此用戶可以像在shell中一樣在Makefile中方便的引用環(huán)境變量。需要注意的是,如果用戶在Makefile中定義了同名的變量,用戶自定義變量將覆蓋同名的環(huán)境變量。此外,Makefile中還有一些預(yù)定義變

23、量和自動變量,但是看起來并不像自定義變量那樣直觀。,4.4 Makefile的隱含規(guī)則,在上面的例子中,幾個產(chǎn)生目標(biāo)文件的命令都是從“.c”的C語言源文件和相關(guān)文件通過編譯產(chǎn)生“.o”目標(biāo)文件,這也是一般的步驟。實際上,make可以使工作更加自動化,也就是說,make知道一些默認(rèn)的動作,它有一些稱作隱含規(guī)則的內(nèi)置的規(guī)則,這些規(guī)則告訴make當(dāng)用戶沒有完整地給出某些命令的時候,應(yīng)該怎樣執(zhí)行。,例如,把生成prog.o和code.o的命令從規(guī)則中刪除,make將會查找隱含規(guī)則,然后會找到并執(zhí)行一個適當(dāng)?shù)拿睢S捎谶@些命令會使用一些變量,因此可以通過改變這些變量來定制make。象在前面的例子中所定義

24、的那樣,make使用變量CC來定義編譯器,并且傳遞變量CFLAGS(編譯器參數(shù))、CPPFLAGS(C語言預(yù)處理器參數(shù))、TARGET_ARCH(目標(biāo)機器的結(jié)構(gòu)定義)給編譯器,然后加上參數(shù)-c,后面跟變量$(第一個依賴文件名),然后是參數(shù)-o加變量$(目標(biāo)文件名)。綜上所述,一個C編譯的具體命令將會是: $ CC $ CFLAGS $ CPPFLAGS $ TARGET_ARCH c $ -o $,在上面的例子中,利用隱含規(guī)則,可以簡化為: OBJS=prog.o code.o CC=gcc test:$ OBJS $ CC o $ $ prog.o:prog.c prog.h code.h

25、code.o:code.c code.h clean: rm f *.o,5 調(diào)試工具GDB,5.1 GDB調(diào)試器簡介 Linux系統(tǒng)中包含了GNU 調(diào)試程序gdb,它是一個用來調(diào)試C和 C+ 程序的調(diào)試器。可以使程序開發(fā)者在程序運行時觀察程序的內(nèi)部結(jié)構(gòu)和內(nèi)存的使用情況。gdb 所提供的一些功能如下所示: 運行程序,設(shè)置所有的能影響程序運行的參數(shù)和環(huán)境; 控制程序在指定的條件下停止運行;,當(dāng)程序停止時,可以檢查程序的狀態(tài); 修改程序的錯誤,并重新運行程序; 動態(tài)監(jiān)視程序中變量的值; 可以單步執(zhí)行代碼,觀察程序的運行狀態(tài)。,gdb的功能非常強大,到目前為止,gdb已能夠支持Moduls-2、Ch

26、ill、Pascal和FORTRAN程序的調(diào)試,但是調(diào)試這些語言的源程序時有一些功能還不能使用。例如調(diào)試FORTRAN程序時還不支持表達式的輸入、輸出變量或類FORTRAN的詞法。 gdb程序調(diào)試的對象是可執(zhí)行文件,而不是程序的源代碼文件。然而,并不是所有的可執(zhí)行文件都可以用gdb調(diào)試。如果要讓產(chǎn)生的可執(zhí)行文件可以用來調(diào)試,需在執(zhí)行g(shù)cc指令編譯程序時,加上-g參數(shù),指定程序在編譯時包含調(diào)試信息。調(diào)試信息包含程序里的每個變量的類型和在可執(zhí)行文件里的地址映射以及源代碼的行號。gdb 利用這些信息使源代碼和機器碼相關(guān)聯(lián)。,5.2 GDB命令的基本使用和應(yīng)用,1gdb基本命令 還可以用下面的方式來運行g(shù)db: gdb filename 其中,filename是要調(diào)試的可執(zhí)行文件。用這種方式運行g(shù)db可以直接指定想要調(diào)試的程序。這和啟動gdb后執(zhí)行file filename命令效果完全一樣。也可以用gdb去檢查一個因程序異常終止而產(chǎn)生的core文件,或者與一個正在運行的程序相連。 gdb支持很多的命令且能實現(xiàn)不同

溫馨提示

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

評論

0/150

提交評論