版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Linux Linux 環(huán)境下的環(huán)境下的 C C語(yǔ)言編程語(yǔ)言編程第一部分第一部分: : Linux Linux下的下的C C編程實(shí)戰(zhàn)之開(kāi)編程實(shí)戰(zhàn)之開(kāi)發(fā)平臺(tái)搭建發(fā)平臺(tái)搭建準(zhǔn)備工作準(zhǔn)備工作n建議在建議在PC內(nèi)存足夠大的情況下,不要直接安裝內(nèi)存足夠大的情況下,不要直接安裝Linux操作系統(tǒng),最好把它安裝在運(yùn)行操作系統(tǒng),最好把它安裝在運(yùn)行VMWare虛擬機(jī)軟件虛擬機(jī)軟件的的Windows平臺(tái)上,如下圖:平臺(tái)上,如下圖: 1. Vim1. Vim和和EmacsEmacs編輯器編輯器n在在Linux平臺(tái)下,可用任意一個(gè)文本編輯工具編輯源代碼。平臺(tái)下,可用任意一個(gè)文本編輯工具編輯源代碼。nVim(vi im
2、prove)是)是Linux下功能強(qiáng)大的編輯器,是由下功能強(qiáng)大的編輯器,是由UNIX系統(tǒng)下的傳統(tǒng)文本編輯器系統(tǒng)下的傳統(tǒng)文本編輯器vi發(fā)展而來(lái),是發(fā)展而來(lái),是vi的一個(gè)增強(qiáng)的一個(gè)增強(qiáng)版本,有彩色和高亮等特性,對(duì)編程有很大幫助。主菜單版本,有彩色和高亮等特性,對(duì)編程有很大幫助。主菜單-編編程程-vi Improved命令來(lái)運(yùn)行命令來(lái)運(yùn)行x-windows下的下的vim。nEmacs即即Editor MACroS(編輯器宏編輯器宏)的縮寫,是一種強(qiáng)大的的縮寫,是一種強(qiáng)大的文本編輯器,在程序員和其他以技術(shù)工作為主的計(jì)算機(jī)用戶文本編輯器,在程序員和其他以技術(shù)工作為主的計(jì)算機(jī)用戶中廣受歡迎。中廣受歡迎。使
3、用使用vimvim編輯編輯helloworldhelloworld程序程序使用使用emacsemacs編輯編輯helloworldhelloworld程序程序2.2.GCC編譯器編譯器nGCC是是Linux平臺(tái)下最重要的開(kāi)發(fā)工具,它是平臺(tái)下最重要的開(kāi)發(fā)工具,它是GNU的的C和和C+編譯器,其基本用法為:編譯器,其基本用法為:ngcc options filenames 該命令按編譯選項(xiàng)(參數(shù)該命令按編譯選項(xiàng)(參數(shù)options)指定的操作對(duì)給)指定的操作對(duì)給定的文件進(jìn)行編譯處理。定的文件進(jìn)行編譯處理。n編譯一輸出編譯一輸出“Hello World”的程序:的程序: main() printf(
4、Hello Worldn);2.2.GCC編譯器編譯器n最簡(jiǎn)單的編譯方法是不指定任何編譯選項(xiàng),它會(huì)為目標(biāo)最簡(jiǎn)單的編譯方法是不指定任何編譯選項(xiàng),它會(huì)為目標(biāo)程序生成默認(rèn)的文件名程序生成默認(rèn)的文件名 a.outgcc o選項(xiàng):編譯來(lái)為將產(chǎn)生的可執(zhí)行文件指定一個(gè)文件名。選項(xiàng):編譯來(lái)為將產(chǎn)生的可執(zhí)行文件指定一個(gè)文件名。例如,將上述名為例如,將上述名為helloworld.c的的C程序編譯為名叫程序編譯為名叫helloworld的可執(zhí)行文件,輸入如下命令:的可執(zhí)行文件,輸入如下命令:gcc -o helloworld helloworld.c2.2.GCC編譯器編譯器- -常用選項(xiàng)常用選項(xiàng)nc選項(xiàng):告訴選
5、項(xiàng):告訴GCC僅把源代碼僅把源代碼(.c文件文件)編譯為目標(biāo)代碼編譯為目標(biāo)代碼(.o文件文件)而跳過(guò)匯編和連接的步驟;它能使編譯多個(gè)而跳過(guò)匯編和連接的步驟;它能使編譯多個(gè)C程序時(shí)的速度更程序時(shí)的速度更快且容易管理。例如用戶將已編輯好的快且容易管理。例如用戶將已編輯好的test.c文件編譯成名為文件編譯成名為test.o的目標(biāo)文件??梢允褂妹畹哪繕?biāo)文件??梢允褂妹?gcc -c s選項(xiàng):告訴選項(xiàng):告訴GCC 在為在為 C代碼產(chǎn)生了匯編語(yǔ)言文件后停止編譯。代碼產(chǎn)生了匯編語(yǔ)言文件后停止編譯。GCC 產(chǎn)生的匯編語(yǔ)言文件的缺省擴(kuò)展名是產(chǎn)生的匯編語(yǔ)言文件的缺省擴(kuò)展名是.s。將生成。將生成hellowo
6、rld.c的匯編代碼,使用的是的匯編代碼,使用的是AT&T匯編。用匯編。用emacs打開(kāi)打開(kāi)匯編代碼如下圖。匯編代碼如下圖。用用emacs打開(kāi)的打開(kāi)的Hello.c的匯編代碼的匯編代碼2.2.GCC編譯器編譯器- -常用選項(xiàng)常用選項(xiàng)nE選項(xiàng):指示編譯器僅對(duì)輸入文件進(jìn)行預(yù)處理,但不匯編和連接選項(xiàng):指示編譯器僅對(duì)輸入文件進(jìn)行預(yù)處理,但不匯編和連接nO(-O1)選項(xiàng):告訴)選項(xiàng):告訴GCC對(duì)源代碼進(jìn)行基本優(yōu)化從而使得程序?qū)υ创a進(jìn)行基本優(yōu)化從而使得程序執(zhí)行地更快;而執(zhí)行地更快;而-O2選項(xiàng)告訴選項(xiàng)告訴GCC產(chǎn)生盡可能小和盡可能快的代產(chǎn)生盡可能小和盡可能快的代碼。使用碼。使用-O2選項(xiàng)編譯的速
7、度比使用選項(xiàng)編譯的速度比使用-O時(shí)慢,但產(chǎn)生的代碼執(zhí)行時(shí)慢,但產(chǎn)生的代碼執(zhí)行速度會(huì)更快。速度會(huì)更快。nWall 選項(xiàng):顯示附加的警告信息。例如在上述程序中去掉選項(xiàng):顯示附加的警告信息。例如在上述程序中去掉 return 0;語(yǔ)句,之后重新編譯語(yǔ)句,之后重新編譯 gcc Wall o hello hello.c將得到的警告信息:將得到的警告信息:hello.c : 5:warning:control reaches end of non-void function3. 3. GDB 調(diào)試器調(diào)試器nGCC用于編譯程序,而用于編譯程序,而Linux的另一個(gè)的另一個(gè)GNU工具工具gdb則用于調(diào)試程則用
8、于調(diào)試程序。序。gdb是一個(gè)用來(lái)調(diào)試是一個(gè)用來(lái)調(diào)試C和和C+程序的強(qiáng)力調(diào)試器,通過(guò)它進(jìn)行程序的強(qiáng)力調(diào)試器,通過(guò)它進(jìn)行一系列調(diào)試工作。一系列調(diào)試工作。ngdb主要提供一下功能主要提供一下功能:n監(jiān)視程序中變量的值得變化監(jiān)視程序中變量的值得變化n設(shè)置斷點(diǎn),使程序在指定的代碼上暫停執(zhí)行,便于觀察設(shè)置斷點(diǎn),使程序在指定的代碼上暫停執(zhí)行,便于觀察n單步執(zhí)行代碼單步執(zhí)行代碼n分析崩潰程序產(chǎn)生的分析崩潰程序產(chǎn)生的core文件文件3. 3. GDB 調(diào)試器調(diào)試器ngdb最常用的命令如下最常用的命令如下nfile:裝入想要調(diào)試的可執(zhí)行文件。:裝入想要調(diào)試的可執(zhí)行文件。nkill:終止正在調(diào)試的程序。:終止正在調(diào)
9、試的程序。 nlist:列表顯示源代碼。:列表顯示源代碼。 nnext:執(zhí)行一行源代碼但不進(jìn)入函數(shù)內(nèi)部。:執(zhí)行一行源代碼但不進(jìn)入函數(shù)內(nèi)部。 nstep:執(zhí)行一行源代碼而且進(jìn)入函數(shù)內(nèi)部。:執(zhí)行一行源代碼而且進(jìn)入函數(shù)內(nèi)部。 nrun:執(zhí)行當(dāng)前被調(diào)試的程序:執(zhí)行當(dāng)前被調(diào)試的程序 nquit:終止:終止gdbnwatch:監(jiān)視一個(gè)變量的值:監(jiān)視一個(gè)變量的值 nbreak:在代碼里設(shè)置斷點(diǎn),程序執(zhí)行到這里時(shí)掛起:在代碼里設(shè)置斷點(diǎn),程序執(zhí)行到這里時(shí)掛起 3. 3. GDB 調(diào)試器調(diào)試器n舉例說(shuō)明怎樣用舉例說(shuō)明怎樣用GDB調(diào)試一個(gè)求調(diào)試一個(gè)求0+1+2+3+99的程序:的程序:/* Filename:sum
10、.c */main() int i, sum; sum = 0; for (i = 0; i 100; i+) sum + = i; printf(the sum of 1+2+.+ is %d, sum);3. 3. GDB 調(diào)試器調(diào)試器3. 3. GDB 調(diào)試器調(diào)試器n執(zhí)行如下命令編譯執(zhí)行如下命令編譯sum.c(加(加-g選項(xiàng)產(chǎn)生選項(xiàng)產(chǎn)生debug信息):信息): gcc g o sum 在命令行上鍵入在命令行上鍵入gdb sum并按回車鍵就可以開(kāi)始調(diào)試并按回車鍵就可以開(kāi)始調(diào)試sum了,了,再運(yùn)行再運(yùn)行run命令執(zhí)行命令執(zhí)行sum,屏幕上將看到如下內(nèi)容:,屏幕上將看到如下內(nèi)容: 3. 3.
11、 GDB 調(diào)試器調(diào)試器nlist命令:命令:list命令用于列出源代碼,對(duì)上述程序運(yùn)行命令用于列出源代碼,對(duì)上述程序運(yùn)行l(wèi)ist,將,將出現(xiàn)如下畫面(源代碼被標(biāo)行號(hào)):出現(xiàn)如下畫面(源代碼被標(biāo)行號(hào)):3. 3. GDB 調(diào)試器調(diào)試器n根據(jù)列出的源程序,如果將斷點(diǎn)設(shè)置在第根據(jù)列出的源程序,如果將斷點(diǎn)設(shè)置在第4行,只需在行,只需在gdb 命令行提示符下鍵入如下命令設(shè)置斷點(diǎn):命令行提示符下鍵入如下命令設(shè)置斷點(diǎn):n(gdb)break 4nBreakpoint 1 at 0 x8048338:file sum.c line 4n這時(shí)再這時(shí)再run,程序會(huì)停止在第,程序會(huì)停止在第4行:行:nStarti
12、ng program:/root/sumnBreakpoint 1,main() at sum.c line 4n4 sum=03. 3. GDB 調(diào)試器調(diào)試器n設(shè)置斷點(diǎn)的另一種語(yǔ)法是設(shè)置斷點(diǎn)的另一種語(yǔ)法是 break ,它在進(jìn)入,它在進(jìn)入指定函數(shù)(指定函數(shù)(function)時(shí)停住。)時(shí)停住。n相反的,相反的,clear用于清除所有的已定義的斷點(diǎn)用于清除所有的已定義的斷點(diǎn)nclear 清除設(shè)置在函數(shù)上的斷點(diǎn);清除設(shè)置在函數(shù)上的斷點(diǎn);nclear 則清除設(shè)置在指定行上的斷點(diǎn)。則清除設(shè)置在指定行上的斷點(diǎn)。3. 3. GDB 調(diào)試器調(diào)試器nwatch命令:用于觀查變量或表達(dá)式的值命令:用于觀查變量
13、或表達(dá)式的值nwatch命令觀查命令觀查sum變量只需要運(yùn)行:變量只需要運(yùn)行:watch sumnwatch命令觀查表達(dá)式:命令觀查表達(dá)式:watch 為表達(dá)式(變量)為表達(dá)式(變量)expr設(shè)置一個(gè)觀察點(diǎn),變量表達(dá)式值設(shè)置一個(gè)觀察點(diǎn),變量表達(dá)式值有變化時(shí),程序會(huì)停止執(zhí)行。有變化時(shí),程序會(huì)停止執(zhí)行。n要觀查當(dāng)前設(shè)置的要觀查當(dāng)前設(shè)置的watch,可以使用,可以使用info watchpoints命令。命令。3. 3. GDB 調(diào)試器調(diào)試器nnext、step命令:命令:nnext、step用于單步執(zhí)行,在執(zhí)行的過(guò)程中,被用于單步執(zhí)行,在執(zhí)行的過(guò)程中,被watch變量的變化情況將實(shí)時(shí)呈現(xiàn)變量的變化
14、情況將實(shí)時(shí)呈現(xiàn)(分別顯示分別顯示Old value和和New value),如下圖:,如下圖:nnext、step命令的區(qū)別在于命令的區(qū)別在于step遇到函數(shù)調(diào)用,會(huì)遇到函數(shù)調(diào)用,會(huì)跳轉(zhuǎn)到該函數(shù)定義的開(kāi)始行去執(zhí)行,而跳轉(zhuǎn)到該函數(shù)定義的開(kāi)始行去執(zhí)行,而next則不則不進(jìn)入到函數(shù)內(nèi)部,它把函數(shù)調(diào)用語(yǔ)句當(dāng)作一條普進(jìn)入到函數(shù)內(nèi)部,它把函數(shù)調(diào)用語(yǔ)句當(dāng)作一條普通語(yǔ)句執(zhí)行。通語(yǔ)句執(zhí)行。4.Make4.Maken編譯和連接的區(qū)別編譯和連接的區(qū)別n編譯器使用源碼文件來(lái)產(chǎn)生某種形式的目標(biāo)文件,在編編譯器使用源碼文件來(lái)產(chǎn)生某種形式的目標(biāo)文件,在編譯過(guò)程中,外部的符號(hào)參考并沒(méi)有被解釋或替換(即外譯過(guò)程中,外部的符號(hào)參
15、考并沒(méi)有被解釋或替換(即外部全局變量和函數(shù)并沒(méi)有被找到)。因此,在編譯階段部全局變量和函數(shù)并沒(méi)有被找到)。因此,在編譯階段所報(bào)的錯(cuò)誤一般都是語(yǔ)法錯(cuò)誤。所報(bào)的錯(cuò)誤一般都是語(yǔ)法錯(cuò)誤。n連接器則用于連接目標(biāo)文件和程序包,生成一個(gè)可執(zhí)行連接器則用于連接目標(biāo)文件和程序包,生成一個(gè)可執(zhí)行程序。在連接階段,一個(gè)目標(biāo)文件中對(duì)別的文件中的符程序。在連接階段,一個(gè)目標(biāo)文件中對(duì)別的文件中的符號(hào)的參考被解釋,如果有符號(hào)不能找到,會(huì)報(bào)告連接錯(cuò)號(hào)的參考被解釋,如果有符號(hào)不能找到,會(huì)報(bào)告連接錯(cuò)誤。誤。4.Make4.Maken編譯和連接的一般步驟是:編譯和連接的一般步驟是:n第一階段把源文件一個(gè)一個(gè)的編譯成目標(biāo)文件,第一階
16、段把源文件一個(gè)一個(gè)的編譯成目標(biāo)文件,n第二階段把所有的目標(biāo)文件加上需要的程序包連接第二階段把所有的目標(biāo)文件加上需要的程序包連接成一個(gè)可執(zhí)行文件。成一個(gè)可執(zhí)行文件。n這樣的過(guò)程需要使用大量的這樣的過(guò)程需要使用大量的gcc命令。而命令。而make則使從則使從大量源文件的編譯和連接工作中解放出來(lái),綜合為一大量源文件的編譯和連接工作中解放出來(lái),綜合為一步完成步完成。4.Make4.MakenGNU Make的主要工作是讀進(jìn)一個(gè)文本文件,稱為的主要工作是讀進(jìn)一個(gè)文本文件,稱為makefile。nmakefile文件記錄了哪些文件(目的文件,目的文件文件記錄了哪些文件(目的文件,目的文件不一定是最后的可執(zhí)
17、行程序,它可以是任何一種文件)不一定是最后的可執(zhí)行程序,它可以是任何一種文件)由哪些文件(依靠文件)產(chǎn)生,用什么命令來(lái)產(chǎn)生。由哪些文件(依靠文件)產(chǎn)生,用什么命令來(lái)產(chǎn)生。nMake依靠此依靠此makefile中的信息檢查磁盤上的文件,如中的信息檢查磁盤上的文件,如果目的文件的創(chuàng)建或修改時(shí)間比它的一個(gè)依靠文件舊果目的文件的創(chuàng)建或修改時(shí)間比它的一個(gè)依靠文件舊的話,的話,make就執(zhí)行相應(yīng)的命令,以便更新目的文件。就執(zhí)行相應(yīng)的命令,以便更新目的文件。4.Make4.Makenmakefile文件的編寫文件的編寫nmakefile文件是一個(gè)文本文件,用于描述整個(gè)項(xiàng)目和各個(gè)文件是一個(gè)文本文件,用于描述整
18、個(gè)項(xiàng)目和各個(gè)文件之間的依賴關(guān)系。它由多個(gè)規(guī)則組成。文件之間的依賴關(guān)系。它由多個(gè)規(guī)則組成。nmakefile文件的規(guī)則遵循以下結(jié)構(gòu)文件的規(guī)則遵循以下結(jié)構(gòu)n#remark 注釋行注釋行ntarget:file1 file2 二進(jìn)制文件或者目標(biāo)文件二進(jìn)制文件或者目標(biāo)文件ncommand1 命令命令ncommand2n4.Make4.Maken例如例如: 下面三個(gè)文件,下面三個(gè)文件,add.h用于聲明用于聲明add函數(shù),函數(shù),add.c提提供兩個(gè)整數(shù)相加的函數(shù)體,而供兩個(gè)整數(shù)相加的函數(shù)體,而main.c中調(diào)用中調(diào)用add函數(shù):函數(shù): /* filename:add.h */extern int add
19、(int i, int j);/* filename:add.c */int add(int i, int j) return i + j;/* filename:main.c */#include add.hmain() int a, b; a = 2; b = 3; printf(the sum of a+b is %d, add(a + b);怎樣為上述三個(gè)文件產(chǎn)生怎樣為上述三個(gè)文件產(chǎn)生makefile呢?呢?4.Make4.Maken為上述三個(gè)文件產(chǎn)生為上述三個(gè)文件產(chǎn)生makefile的方法如下:的方法如下: test : main.o add.o gcc main.o add.o -
20、o test main.o : main.c add.h gcc -c main.c -o main.o add.o : add.c add.h gcc -c add.c -o add.o 4.Make4.Maken上述上述makefile文件的含義文件的含義n利用利用add.c和和add.h文件執(zhí)行文件執(zhí)行g(shù)cc -c add.c -o add.o命令產(chǎn)生命令產(chǎn)生add.o目標(biāo)代碼。目標(biāo)代碼。n利用利用main.c和和add.h文件執(zhí)行文件執(zhí)行g(shù)cc -c main.c -o main.o命令命令產(chǎn)生產(chǎn)生main.o目標(biāo)代碼。目標(biāo)代碼。n最后利用最后利用main.o和和add.o文件(兩個(gè)模
21、塊的目標(biāo)代碼)執(zhí)文件(兩個(gè)模塊的目標(biāo)代碼)執(zhí)行行g(shù)cc main.o add.o -o test命令產(chǎn)生可執(zhí)行文件命令產(chǎn)生可執(zhí)行文件test。n可以使用可以使用gcc -MM main.c自動(dòng)尋找源文件中的頭文件,并自動(dòng)尋找源文件中的頭文件,并形成依賴關(guān)系。形成依賴關(guān)系。n輸出為:輸出為:main.o main.c add.h4.Make4.Maken可在可在makefile中加入變量。另外,環(huán)境變量在中加入變量。另外,環(huán)境變量在make過(guò)程中過(guò)程中也被解釋成也被解釋成make的變量。這些變量是大小寫敏感的,一般的變量。這些變量是大小寫敏感的,一般使用大寫字母。使用大寫字母。n要定義一個(gè)變量,
22、只需要在一行的開(kāi)始寫下這個(gè)變量的名要定義一個(gè)變量,只需要在一行的開(kāi)始寫下這個(gè)變量的名字,后面跟一個(gè)字,后面跟一個(gè)=號(hào),再跟變量的值。引用變量的方法是寫號(hào),再跟變量的值。引用變量的方法是寫一個(gè)一個(gè)$符號(hào),后面跟(變量名)。符號(hào),后面跟(變量名)。4.Make4.Maken把前面的把前面的 makefile 利用變量重寫一遍(并假設(shè)使用利用變量重寫一遍(并假設(shè)使用-Wall -O g編譯選項(xiàng)):編譯選項(xiàng)):nOBJS = main.o add.onCC = gccnCFLAGS = -Wall -O -gntest : $(OBJS)n$(CC) $(OBJS) -o testnmain.o :
23、main.c add.hn$(CC) $(CFLAGS) -c main.c -o main.onadd.o : add.c add.hn$(CC) $(CFLAGS) -c add.c -o add.o 4.Make4.Makenmakefile 中還可定義清除(中還可定義清除(clean)目標(biāo),可用來(lái)清除)目標(biāo),可用來(lái)清除編譯過(guò)程中產(chǎn)生的中間文件,例如在上述編譯過(guò)程中產(chǎn)生的中間文件,例如在上述makefile文件文件中添加下列代碼:中添加下列代碼: nclean: rm -f *.on運(yùn)行運(yùn)行make clean時(shí),將執(zhí)行時(shí),將執(zhí)行rm -f *.o命令,刪除所有編命令,刪除所有編譯過(guò)程中
24、產(chǎn)生的中間文件。譯過(guò)程中產(chǎn)生的中間文件。4.Make4.MakenMake的運(yùn)行的運(yùn)行nGUN make默認(rèn)在當(dāng)前的目錄下一次查找默認(rèn)在當(dāng)前的目錄下一次查找GUNmake文件,文件,Makefile文件和文件和makefile文件,文件,找到后讀取文件執(zhí)行。找到后讀取文件執(zhí)行。n給給make命令指定一個(gè)特殊名字的命令指定一個(gè)特殊名字的makefile文件文件nmake f hchen.mk4.Make4.Maken自己動(dòng)手編寫自己動(dòng)手編寫makefile仍然是很復(fù)雜和煩瑣的,而且很仍然是很復(fù)雜和煩瑣的,而且很容易出錯(cuò)。因此,容易出錯(cuò)。因此,GNU也提供了也提供了Automake和和Autoco
25、nf來(lái)輔助快速自動(dòng)產(chǎn)生來(lái)輔助快速自動(dòng)產(chǎn)生makefile。4.Make4.Maken使用使用autoconf和和automake來(lái)進(jìn)行自動(dòng)化配置和生成來(lái)進(jìn)行自動(dòng)化配置和生成Makefile的流程可以概括如下:的流程可以概括如下:n運(yùn)行運(yùn)行autoscan命令。命令。n將將configure.scan文件重命名為文件重命名為configure.in,并修改,并修改configure.in文件。文件。n運(yùn)行運(yùn)行aclocal命令得到命令得到aclocal.m4文件。文件。n運(yùn)行運(yùn)行autoconf命令得到命令得到configure文件。文件。n在工程目錄下新建在工程目錄下新建Makefile.am
26、文件,如果存在子目錄,文件,如果存在子目錄,子目錄中也要?jiǎng)?chuàng)建此文件。子目錄中也要?jiǎng)?chuàng)建此文件。n將將/usr/share/automake-1.X/目錄下的目錄下的depcomp和和compile文件復(fù)制到需要處理目錄下。文件復(fù)制到需要處理目錄下。n運(yùn)行運(yùn)行automake -a命令得到命令得到Makefile.in文件。文件。n運(yùn)行運(yùn)行./configure腳本腳本 4.Make4.Maken從例子程序從例子程序helloworld開(kāi)始。過(guò)程如下:開(kāi)始。過(guò)程如下:n新建三個(gè)文件:新建三個(gè)文件: helloworld.cconfigure.inMakefile.amn然后執(zhí)行然后執(zhí)行 acloc
27、al; autoconf; automake -add-missing; ./configure; make; ./helloworld nMakefile被產(chǎn)生出來(lái),而且可以將被產(chǎn)生出來(lái),而且可以將helloworld.c編譯通編譯通過(guò)。過(guò)。小結(jié)小結(jié)n本部分主要闡述了本部分主要闡述了Linux程序的編寫、編譯、調(diào)試方程序的編寫、編譯、調(diào)試方法及法及make,實(shí)際上是引導(dǎo)學(xué)習(xí)怎樣在,實(shí)際上是引導(dǎo)學(xué)習(xí)怎樣在Linux下編程,下編程,為后續(xù)章節(jié)做好準(zhǔn)備。為后續(xù)章節(jié)做好準(zhǔn)備。第二部分第二部分 LinuxLinux下的下的C C編程實(shí)戰(zhàn)之編程實(shí)戰(zhàn)之文件系統(tǒng)編程文件系統(tǒng)編程 LinuxLinux平臺(tái)下文
28、件編程平臺(tái)下文件編程n在在Linux平臺(tái)下對(duì)文件編程可以使用兩類函數(shù):平臺(tái)下對(duì)文件編程可以使用兩類函數(shù):nLinux操作系統(tǒng)文件操作系統(tǒng)文件API;nC語(yǔ)言語(yǔ)言I/O庫(kù)函數(shù)。庫(kù)函數(shù)。 n前者依賴于前者依賴于Linux系統(tǒng)調(diào)用,后者實(shí)際上與操作系統(tǒng)是系統(tǒng)調(diào)用,后者實(shí)際上與操作系統(tǒng)是獨(dú)立的,因?yàn)樵谌魏尾僮飨到y(tǒng)下,使用獨(dú)立的,因?yàn)樵谌魏尾僮飨到y(tǒng)下,使用C語(yǔ)言語(yǔ)言I/O庫(kù)函庫(kù)函數(shù)操作文件的方法都是相同的。數(shù)操作文件的方法都是相同的。 1. Linux1. Linux文件文件API-API-創(chuàng)建創(chuàng)建n創(chuàng)建創(chuàng)建nint create(const char *filename, mode_t mode);
29、參數(shù)參數(shù)mode指定新建文件的存取權(quán)限,它同指定新建文件的存取權(quán)限,它同umask一起決定文件的最終權(quán)限(一起決定文件的最終權(quán)限(mode&umask).numask代表了文件在創(chuàng)建時(shí)需要去掉的一些存取權(quán)代表了文件在創(chuàng)建時(shí)需要去掉的一些存取權(quán)限。限。umask可通過(guò)系統(tǒng)調(diào)用可通過(guò)系統(tǒng)調(diào)用umask()來(lái)改變:來(lái)改變: int umask(int newmask); 該調(diào)用將該調(diào)用將umask設(shè)置為設(shè)置為newmask,然后返回舊,然后返回舊的的umask,它只影響讀、寫和執(zhí)行權(quán)限。,它只影響讀、寫和執(zhí)行權(quán)限。1. Linux1. Linux文件文件API-API-創(chuàng)建創(chuàng)建nmode可以
30、是以下情況的組合,可以是以下情況的組合,可以通過(guò)上述宏進(jìn)行可以通過(guò)上述宏進(jìn)行“或或”邏輯產(chǎn)生標(biāo)志。邏輯產(chǎn)生標(biāo)志。 標(biāo)志標(biāo)志含義含義S_IRUSR 用戶可以讀用戶可以讀 S_IWUSR 用戶可以寫用戶可以寫 S_IXUSR 用戶可以執(zhí)行用戶可以執(zhí)行 S_IRWXU 用戶可以讀、寫、執(zhí)行用戶可以讀、寫、執(zhí)行 S_IRGRP 組可以讀組可以讀 S_IWGRP 組可以寫組可以寫S_IXGRP 組可以執(zhí)行組可以執(zhí)行 S_IRWXG 組可以讀寫執(zhí)行組可以讀寫執(zhí)行 1. Linux1. Linux文件文件API-API-創(chuàng)建創(chuàng)建nmode可以是以下情況的組合,可以是以下情況的組合,可以通過(guò)上述宏進(jìn)行可以通過(guò)
31、上述宏進(jìn)行“或或”邏輯產(chǎn)生標(biāo)志。邏輯產(chǎn)生標(biāo)志。標(biāo)志標(biāo)志含義含義S_IROTH其他人可以讀其他人可以讀S_IWOTH其他人可以寫其他人可以寫S_IXOTH其他人可以執(zhí)行其他人可以執(zhí)行S_IRWXO其他人可以讀、寫、執(zhí)行其他人可以讀、寫、執(zhí)行S_ISUID設(shè)置用戶執(zhí)行設(shè)置用戶執(zhí)行IDS_ISGID設(shè)置組的執(zhí)行設(shè)置組的執(zhí)行ID1. Linux1. Linux文件文件API-API-創(chuàng)建創(chuàng)建n用數(shù)字來(lái)表示:用數(shù)字來(lái)表示:Linux總共用總共用5個(gè)數(shù)字來(lái)表示文件的各個(gè)數(shù)字來(lái)表示文件的各種權(quán)限:種權(quán)限:n第一位表示設(shè)置用戶第一位表示設(shè)置用戶ID;n第二位表示設(shè)置組第二位表示設(shè)置組ID;n第三位表示用戶自己
32、的權(quán)限位;第三位表示用戶自己的權(quán)限位;n第四位表示組的權(quán)限;第四位表示組的權(quán)限;n最后一位表示其他人的權(quán)限。每個(gè)數(shù)字可以取最后一位表示其他人的權(quán)限。每個(gè)數(shù)字可以取1(執(zhí)執(zhí)行權(quán)限行權(quán)限)、2(寫權(quán)限寫權(quán)限)、4(讀權(quán)限讀權(quán)限)、0(無(wú)無(wú))或者是這或者是這些值的和。些值的和。1. Linux1. Linux文件文件API-API-創(chuàng)建創(chuàng)建n用數(shù)字來(lái)表示:用數(shù)字來(lái)表示:n例如,要?jiǎng)?chuàng)建一個(gè)用戶可讀、可寫、可執(zhí)行,但是例如,要?jiǎng)?chuàng)建一個(gè)用戶可讀、可寫、可執(zhí)行,但是組沒(méi)有權(quán)限,其他人可以讀、可以執(zhí)行的文件,并組沒(méi)有權(quán)限,其他人可以讀、可以執(zhí)行的文件,并設(shè)置用戶設(shè)置用戶ID位。位。n應(yīng)該使用的模式是應(yīng)該使用的
33、模式是1(設(shè)置用戶設(shè)置用戶ID)、0(不設(shè)置組不設(shè)置組ID)、7(1+2+4,讀、寫、執(zhí)行,讀、寫、執(zhí)行)、0(沒(méi)有權(quán)限沒(méi)有權(quán)限)、5(1+4,讀、,讀、執(zhí)行執(zhí)行)即即10705 1. Linux1. Linux文件文件API-API-打開(kāi)打開(kāi)n打開(kāi)打開(kāi)nint open(const char *pathname, int flags);nint open(const char *pathname, int flags, mode_t mode); n如果文件打開(kāi)成功,如果文件打開(kāi)成功,open函數(shù)會(huì)返回一個(gè)文件描述符,函數(shù)會(huì)返回一個(gè)文件描述符,以后對(duì)該文件的所有操作就可以通過(guò)對(duì)這個(gè)文件描述符
34、以后對(duì)該文件的所有操作就可以通過(guò)對(duì)這個(gè)文件描述符進(jìn)行操作來(lái)實(shí)現(xiàn)。進(jìn)行操作來(lái)實(shí)現(xiàn)。nopen函數(shù)有兩個(gè)形式,其中函數(shù)有兩個(gè)形式,其中pathname是要打開(kāi)的文件名是要打開(kāi)的文件名(包含路徑名稱,缺省是認(rèn)為在當(dāng)前路徑下面包含路徑名稱,缺省是認(rèn)為在當(dāng)前路徑下面) 。1. Linux1. Linux文件文件API-API-打開(kāi)打開(kāi)n打開(kāi)打開(kāi)nflags可以是下面的一個(gè)值或者是幾個(gè)值的組合,可以是下面的一個(gè)值或者是幾個(gè)值的組合,O_RDONLY、O_WRONLY、O_RDWR三個(gè)標(biāo)志只能三個(gè)標(biāo)志只能使用任意的一個(gè)使用任意的一個(gè)。1. Linux1. Linux文件文件API-API-打開(kāi)打開(kāi)n打開(kāi)打開(kāi)
35、n如果使用了如果使用了O_CREATE標(biāo)志,則使用的函數(shù)是標(biāo)志,則使用的函數(shù)是int open(const char *pathname,int flags,mode_t mode); 這時(shí)這時(shí)要指定要指定mode標(biāo)志,用來(lái)表示文件的訪問(wèn)權(quán)限。以標(biāo)志,用來(lái)表示文件的訪問(wèn)權(quán)限。以O(shè)_CREAT為標(biāo)志的為標(biāo)志的open實(shí)際上實(shí)現(xiàn)了文件創(chuàng)建的功能。實(shí)際上實(shí)現(xiàn)了文件創(chuàng)建的功能。n例如:例如: open(test, O_CREAT, 10705); open(test, O_CREAT, S_IRWXU | S_IROTH | S_IXOTH | S_ISUID );1. Linux1. Linux文件
36、文件API-API-讀寫讀寫n讀寫讀寫nLinux中提供文件讀寫的系統(tǒng)調(diào)用是中提供文件讀寫的系統(tǒng)調(diào)用是read、write函數(shù):函數(shù): int read(int fd, const void *buf, size_t length); int write(int fd, const void *buf, size_t length);n參數(shù)參數(shù)buf為指向緩沖區(qū)的指針,為指向緩沖區(qū)的指針,length為緩沖區(qū)的大為緩沖區(qū)的大小(以字節(jié)為單位)。小(以字節(jié)為單位)。1. Linux1. Linux文件文件API-API-讀寫讀寫nint read(int fd, const void *buf,
37、 size_t length);n函數(shù)函數(shù)read實(shí)現(xiàn)從文件描述符實(shí)現(xiàn)從文件描述符fd所指定的文件中讀取所指定的文件中讀取length個(gè)字節(jié)到個(gè)字節(jié)到buf所指向的緩沖區(qū)中,返回值為實(shí)際讀所指向的緩沖區(qū)中,返回值為實(shí)際讀取的字節(jié)數(shù)。取的字節(jié)數(shù)。nint write(int fd, const void *buf, size_t length);n函數(shù)函數(shù)write實(shí)現(xiàn)將把實(shí)現(xiàn)將把length個(gè)字節(jié)從個(gè)字節(jié)從buf指向的緩沖區(qū)中寫指向的緩沖區(qū)中寫到文件描述符到文件描述符fd所指向的文件中,返回值為實(shí)際寫入的所指向的文件中,返回值為實(shí)際寫入的字節(jié)數(shù)。字節(jié)數(shù)。1. Linux1. Linux文件文件
38、API-API-定位定位n定位:定位:n對(duì)于隨機(jī)文件,我們可以隨機(jī)的指定位置讀寫,使用如對(duì)于隨機(jī)文件,我們可以隨機(jī)的指定位置讀寫,使用如下函數(shù)進(jìn)行定位:下函數(shù)進(jìn)行定位: int lseek(int fd, offset_t offset, int whence);nlseek()將文件讀寫指針相對(duì)將文件讀寫指針相對(duì)whence移動(dòng)移動(dòng)offset個(gè)字節(jié)。操個(gè)字節(jié)。操作成功時(shí),返回文件指針相對(duì)于文件頭的位置。參數(shù)作成功時(shí),返回文件指針相對(duì)于文件頭的位置。參數(shù)whence可使用下述值:可使用下述值:nSEEK_SET:相對(duì)文件開(kāi)頭:相對(duì)文件開(kāi)頭nSEEK_CUR:相對(duì)文件讀寫指針的當(dāng)前位置:相對(duì)文
39、件讀寫指針的當(dāng)前位置nSEEK_END:相對(duì)文件末尾:相對(duì)文件末尾1. Linux1. Linux文件文件API-API-定位定位n定位:定位:noffset可取負(fù)值,例如下述調(diào)用可將文件指針相對(duì)當(dāng)前位可取負(fù)值,例如下述調(diào)用可將文件指針相對(duì)當(dāng)前位置向前移動(dòng)置向前移動(dòng)5個(gè)字節(jié):個(gè)字節(jié): lseek(fd, -5, SEEK_CUR);n由于由于lseek函數(shù)的返回值為文件指針相對(duì)于文件頭的位置,函數(shù)的返回值為文件指針相對(duì)于文件頭的位置,因此下列調(diào)用的返回值就是文件的長(zhǎng)度:因此下列調(diào)用的返回值就是文件的長(zhǎng)度: lseek(fd, 0, SEEK_END);1. Linux1. Linux文件文件A
40、PI-API-關(guān)閉關(guān)閉n關(guān)閉關(guān)閉n當(dāng)操作完成以后,要關(guān)閉文件,只要調(diào)用當(dāng)操作完成以后,要關(guān)閉文件,只要調(diào)用close即可,即可,其 中其 中 f d 是 要 關(guān) 閉 的 文 件 描 述 符 :是 要 關(guān) 閉 的 文 件 描 述 符 : int close(int fd);1. Linux1. Linux文件文件API-API-編程實(shí)例編程實(shí)例n例程:編寫一個(gè)程序,在當(dāng)前目錄下創(chuàng)建用戶可讀寫例程:編寫一個(gè)程序,在當(dāng)前目錄下創(chuàng)建用戶可讀寫文件文件“hello.txt”,在其中寫入,在其中寫入“Hello, software weekly”,關(guān)閉該文件。再次打開(kāi)該文件,讀取其中的,關(guān)閉該文件。再次打
41、開(kāi)該文件,讀取其中的內(nèi)容并輸出在屏幕上。內(nèi)容并輸出在屏幕上。n#include /類型類型n#include /獲取文件屬性獲取文件屬性n#include /文件描述詞操作文件描述詞操作n#include #define LENGTH 100nmain()int fd, len;char strLENGTH; fd = open(“hello.txt”, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); /* 創(chuàng)建并打開(kāi)文件創(chuàng)建并打開(kāi)文件 ,以讀寫的方式打開(kāi),用戶可,以讀寫的方式打開(kāi),用戶可以讀、用戶可以寫以讀、用戶可以寫*/1. Linux1. Linux文件文件A
42、PI-API-編程實(shí)例編程實(shí)例nif (fd) write(fd, Hello, Software Weekly, strlen(Hello, software weekly); /* 寫入寫入Hello, software weekly字符串字符串 */close(fd);nfd = open(“hello.txt”, O_RDWR); /以讀寫方式打開(kāi)以讀寫方式打開(kāi) len = read(fd, str, LENGTH); /* 讀取文件內(nèi)容讀取文件內(nèi)容 */strlen = 0;printf(%sn, str);close(fd); 1. Linux1. Linux文件文件API-API
43、-編程實(shí)例編程實(shí)例1. Linux1. Linux文件文件API-API-編程實(shí)例編程實(shí)例n編譯并運(yùn)行,執(zhí)行結(jié)果如下編譯并運(yùn)行,執(zhí)行結(jié)果如下nrootdl root#gcc g o hello ./rootdl root# ./hellonHello,software weekly3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)nC庫(kù)函數(shù)的文件操作實(shí)際上是獨(dú)立于具體的操作系統(tǒng)庫(kù)函數(shù)的文件操作實(shí)際上是獨(dú)立于具體的操作系統(tǒng)平臺(tái)的,不管是在平臺(tái)的,不管是在DOS、Windows、Linux還是在還是在VxWorks中都是這些函數(shù)中都是這些函數(shù).3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -創(chuàng)建和打開(kāi)創(chuàng)建和打開(kāi)n創(chuàng)建和打開(kāi)創(chuàng)
44、建和打開(kāi)nFILE *fopen(const char *path, const char *mode);nfopen()實(shí)現(xiàn)打開(kāi)指定文件,實(shí)現(xiàn)打開(kāi)指定文件,參數(shù)參數(shù)path字符串包含欲字符串包含欲打開(kāi)的文件路徑及文件名打開(kāi)的文件路徑及文件名 ,mode為打開(kāi)模式為打開(kāi)模式.n返回值:文件指針名。必須被說(shuō)明為返回值:文件指針名。必須被說(shuō)明為FILE類型的指類型的指針變量針變量 。3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -創(chuàng)建和打開(kāi)創(chuàng)建和打開(kāi)nC語(yǔ)言中支持的打開(kāi)模式如下表,其中語(yǔ)言中支持的打開(kāi)模式如下表,其中b用于區(qū)分二進(jìn)制文件用于區(qū)分二進(jìn)制文件和文本文件,在和文本文件,在DOS、Windows系統(tǒng)
45、中是有區(qū)分的,但系統(tǒng)中是有區(qū)分的,但Linux不區(qū)分二進(jìn)制文件和文本文件。不區(qū)分二進(jìn)制文件和文本文件。標(biāo)志標(biāo)志含義含義r, rb以只讀方式打開(kāi)以只讀方式打開(kāi)w, wb以只寫方式打開(kāi)。如果文件不存在,則創(chuàng)建該文件,以只寫方式打開(kāi)。如果文件不存在,則創(chuàng)建該文件,否則文件被截?cái)喾駝t文件被截?cái)郺, ab以追加方式打開(kāi)。如果文件不存在,則創(chuàng)建該文件以追加方式打開(kāi)。如果文件不存在,則創(chuàng)建該文件r+, r+b, rb+以讀寫方式打開(kāi)以讀寫方式打開(kāi)+, w+b, wh+以讀寫方式打開(kāi)。如果文件不存在時(shí),創(chuàng)建新文件,以讀寫方式打開(kāi)。如果文件不存在時(shí),創(chuàng)建新文件,否則文件被截?cái)喾駝t文件被截?cái)郺+, a+b, ab
46、+以讀和追加方式打開(kāi)。如果文件不存在,創(chuàng)建新文件以讀和追加方式打開(kāi)。如果文件不存在,創(chuàng)建新文件3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -讀寫讀寫n讀寫:讀寫:C庫(kù)函數(shù)支持以字符、字符串等為單位,支持庫(kù)函數(shù)支持以字符、字符串等為單位,支持按照某中格式進(jìn)行文件的讀寫,這一組函數(shù)為:按照某中格式進(jìn)行文件的讀寫,這一組函數(shù)為:nint fgetc(FILE *stream); 從流中讀一個(gè)字符從流中讀一個(gè)字符nint fputc(int c, FILE *stream);送一個(gè)字符到流中送一個(gè)字符到流中nchar *fgets(char *s, int n, FILE *stream);從流中讀從流中讀取
47、一字符串取一字符串 nint fputs(const char *s, FILE *stream);送一個(gè)字符送一個(gè)字符串到流中串到流中3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -讀寫讀寫nint fprintf(FILE *stream, const char *format, .);n傳送格式化輸出到一個(gè)文件中,成功時(shí)返回轉(zhuǎn)換的傳送格式化輸出到一個(gè)文件中,成功時(shí)返回轉(zhuǎn)換的字節(jié)數(shù),失敗時(shí)返回一個(gè)負(fù)數(shù)。字節(jié)數(shù),失敗時(shí)返回一個(gè)負(fù)數(shù)。 fprintf( stream, %s%c, s, c ); fprintf( stream, %dn, i ); nint fscanf (FILE *stream,
48、const char *format, .);n從一個(gè)流中執(zhí)行格式化輸入從一個(gè)流中執(zhí)行格式化輸入 if (fscanf(stdin, %d, &i) printf(The integer read was: %dn,i); 3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -讀寫讀寫n讀寫:讀寫:nsize_t fread(void *ptr, size_t size, size_t n, FILE *stream);nsize_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream);nfread()實(shí)現(xiàn)從流實(shí)現(xiàn)從流stream
49、中讀取中讀取n個(gè)字段,每個(gè)字段為個(gè)字段,每個(gè)字段為size字節(jié),并將讀取的字段放入字節(jié),并將讀取的字段放入ptr所指的字符數(shù)組中,所指的字符數(shù)組中,返回實(shí)際已讀取的字段數(shù)。返回實(shí)際已讀取的字段數(shù)。nwrite()實(shí)現(xiàn)從緩沖區(qū)實(shí)現(xiàn)從緩沖區(qū)ptr所指的數(shù)組中把所指的數(shù)組中把n個(gè)字段寫到個(gè)字段寫到流流stream中,每個(gè)字段長(zhǎng)為中,每個(gè)字段長(zhǎng)為size個(gè)字節(jié),返回實(shí)際寫入個(gè)字節(jié),返回實(shí)際寫入的字段數(shù)。的字段數(shù)。3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -定位定位n定位定位 :C庫(kù)函數(shù)還提供了讀寫過(guò)程中的定位能力,這些函庫(kù)函數(shù)還提供了讀寫過(guò)程中的定位能力,這些函數(shù)包括:數(shù)包括:nint fgetpos(FI
50、LE *stream, fpos_t *pos); /將文件流的文件位置指示符存儲(chǔ)在將文件流的文件位置指示符存儲(chǔ)在pos變量中變量中nint fsetpos(FILE *stream, const fpos_t *pos);/將文件指針定位在將文件指針定位在pos指定的位置上指定的位置上 n返回值:成功返回返回值:成功返回0,否則返回非,否則返回非0。n#include nvoid main( void )nn FILE *fp;n fpos_t pos;n char buffer50;n if( (fp = fopen( test.txt, rb ) = NULL ) /*以只讀方以只讀方式
51、打開(kāi)名為式打開(kāi)名為test.txt的文件的文件*/n printf( Trouble opening filen );n elsen n pos = 10; /*設(shè)置設(shè)置pos值值*/n if( fsetpos( fp, &pos ) != 0 ) /*應(yīng)用應(yīng)用fsetpos函數(shù)將文件指函數(shù)將文件指針針fp按照按照pos指定的位置在文件中定位指定的位置在文件中定位*/n perror( fsetpos error );nelse n /*從新定位的文件指針開(kāi)始讀取從新定位的文件指針開(kāi)始讀取16個(gè)字符到個(gè)字符到buffer緩沖區(qū)緩沖區(qū)*/nfread( buffer, sizeof( c
52、har ), 16, fp );nprintf( 16 bytes at byte %ld: %.16sn, pos, buffer ); /*顯顯示結(jié)果示結(jié)果*/n n n fclose( fp );n 3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -定位定位n首先,程序以只讀方式打開(kāi)名為首先,程序以只讀方式打開(kāi)名為test.txt的文件。在這里,的文件。在這里,test.txt文件中已存入字符串文件中已存入字符串This is a test for testing the function of fsetpos.n將將pos設(shè)置為設(shè)置為10。應(yīng)用。應(yīng)用fsetpos函數(shù)將文件指針函數(shù)將文件指針fp按
53、照按照pos指定的位置在文件中定位。這樣文件指針指定的位置在文件中定位。這樣文件指針fp指向字符串指向字符串中中test的字母的字母t。n再?gòu)男露ㄎ坏奈募羔橀_(kāi)始讀取再?gòu)男露ㄎ坏奈募羔橀_(kāi)始讀取16個(gè)字符到個(gè)字符到buffer緩沖緩沖區(qū),也就是說(shuō)讀取字符串區(qū),也就是說(shuō)讀取字符串test for testing到緩沖區(qū)到緩沖區(qū)buffer。n最后顯示結(jié)果:最后顯示結(jié)果:16 bytes at byte 10: test for testing 3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -定位定位nint fseek(FILE *stream, long offset, int whence);nstr
54、eam為文件指針為文件指針noffset為偏移量,整數(shù)表示正向偏移,負(fù)數(shù)為負(fù)向偏移為偏移量,整數(shù)表示正向偏移,負(fù)數(shù)為負(fù)向偏移nwhence設(shè)定從文件的哪里開(kāi)始偏移,可能取值為:設(shè)定從文件的哪里開(kāi)始偏移,可能取值為:nSEEK_SET: 文件開(kāi)頭文件開(kāi)頭 0nSEEK_CUR: 當(dāng)前位置當(dāng)前位置 1nSEEK_END: 文件結(jié)尾文件結(jié)尾 2nfseek(fp,100L,0);把把fp指針移動(dòng)到離文件開(kāi)頭指針移動(dòng)到離文件開(kāi)頭100字節(jié)處;字節(jié)處;nfseek(fp,100L,1);把把fp指針移動(dòng)到離文件當(dāng)前位置指針移動(dòng)到離文件當(dāng)前位置100字節(jié)處;字節(jié)處;nfseek(fp,100L,2);把把
55、fp指針退回到離文件結(jié)尾指針退回到離文件結(jié)尾100字節(jié)處。字節(jié)處。3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -關(guān)閉關(guān)閉n關(guān)閉:關(guān)閉:n利用利用C庫(kù)函數(shù)關(guān)閉文件的操作:庫(kù)函數(shù)關(guān)閉文件的操作: int fclose (FILE *stream);3.C3.C語(yǔ)言庫(kù)函數(shù)語(yǔ)言庫(kù)函數(shù)- -編程實(shí)例編程實(shí)例n例程:編寫一個(gè)程序,在當(dāng)前目錄下創(chuàng)建用戶可讀寫例程:編寫一個(gè)程序,在當(dāng)前目錄下創(chuàng)建用戶可讀寫文件文件“hello.txt”,在其中寫入,在其中寫入“Hello, software weekly”,關(guān)閉該文件。再次打開(kāi)該文件,讀取其中的,關(guān)閉該文件。再次打開(kāi)該文件,讀取其中的內(nèi)容并輸出在屏幕上。內(nèi)容并輸出在屏
56、幕上。n#include #define LENGTH 100nmain()FILE *fd;char strLENGTH;fd = fopen(hello.txt, w+); /* 創(chuàng)建并打開(kāi)文件創(chuàng)建并打開(kāi)文件 */if (fd)fputs(Hello, Software Weekly, fd); /* 寫入寫入Hello, software weekly字符串字符串 */fclose(fd);fd = fopen(hello.txt, r);fgets(str, LENGTH, fd); /* 讀取文件內(nèi)容讀取文件內(nèi)容 */printf(%sn, str);fclose(fd);3.3.小
57、結(jié)小結(jié)nLinux提供的虛擬文件系統(tǒng)為多種文件系統(tǒng)提供了統(tǒng)提供的虛擬文件系統(tǒng)為多種文件系統(tǒng)提供了統(tǒng)一的接口,一的接口,Linux的文件編程有兩種途徑:的文件編程有兩種途徑:n基于基于Linux系統(tǒng)調(diào)用;系統(tǒng)調(diào)用;n基于基于C庫(kù)函數(shù)庫(kù)函數(shù)n這兩種編程所涉及到文件操作有新建、打開(kāi)、讀寫和這兩種編程所涉及到文件操作有新建、打開(kāi)、讀寫和關(guān)閉,對(duì)隨機(jī)文件還可以定位。關(guān)閉,對(duì)隨機(jī)文件還可以定位。 第二部分第二部分 LinuxLinux下的下的C C編程實(shí)戰(zhàn)之進(jìn)編程實(shí)戰(zhàn)之進(jìn)程控制與進(jìn)程通信編程程控制與進(jìn)程通信編程 1. 1.進(jìn)程的基本進(jìn)程的基本概念概念n進(jìn)程是具有一定功能的程序,是關(guān)于一個(gè)數(shù)據(jù)集合的一次進(jìn)程
58、是具有一定功能的程序,是關(guān)于一個(gè)數(shù)據(jù)集合的一次執(zhí)行過(guò)程。多個(gè)進(jìn)程可以同時(shí)運(yùn)行。執(zhí)行過(guò)程。多個(gè)進(jìn)程可以同時(shí)運(yùn)行。nLinux進(jìn)程在內(nèi)存中包含三部分?jǐn)?shù)據(jù):進(jìn)程在內(nèi)存中包含三部分?jǐn)?shù)據(jù):n代碼段:存放了程序的代碼,代碼段可以為機(jī)器中運(yùn)行代碼段:存放了程序的代碼,代碼段可以為機(jī)器中運(yùn)行同一程序的數(shù)個(gè)進(jìn)程共享。同一程序的數(shù)個(gè)進(jìn)程共享。n堆棧段:存放的是子程序(函數(shù))的返回地址、子程序堆棧段:存放的是子程序(函數(shù))的返回地址、子程序的參數(shù)及程序的局部變量。的參數(shù)及程序的局部變量。n數(shù)據(jù)段:存放程序的全局變量、常數(shù)以及動(dòng)態(tài)數(shù)據(jù)分配數(shù)據(jù)段:存放程序的全局變量、常數(shù)以及動(dòng)態(tài)數(shù)據(jù)分配的數(shù)據(jù)空間。堆棧段和數(shù)據(jù)段不能為
59、運(yùn)行同一程序的數(shù)的數(shù)據(jù)空間。堆棧段和數(shù)據(jù)段不能為運(yùn)行同一程序的數(shù)個(gè)進(jìn)程共享。個(gè)進(jìn)程共享。2.2.進(jìn)程控制進(jìn)程控制- -進(jìn)程的創(chuàng)建進(jìn)程的創(chuàng)建n(1)派生進(jìn)程)派生進(jìn)程n系統(tǒng)調(diào)用系統(tǒng)調(diào)用fork用于派生一個(gè)進(jìn)程,其說(shuō)明如下:用于派生一個(gè)進(jìn)程,其說(shuō)明如下: #include pid_t fork(void); pid_t vfork(void);n調(diào)用調(diào)用fork時(shí),系統(tǒng)創(chuàng)建一個(gè)與當(dāng)前進(jìn)程(父進(jìn)程)時(shí),系統(tǒng)創(chuàng)建一個(gè)與當(dāng)前進(jìn)程(父進(jìn)程)相同的新進(jìn)程(子進(jìn)程)。子進(jìn)程是父進(jìn)程的一個(gè)相同的新進(jìn)程(子進(jìn)程)。子進(jìn)程是父進(jìn)程的一個(gè)復(fù)制,子進(jìn)程拷貝父進(jìn)程的數(shù)據(jù)段、代碼段復(fù)制,子進(jìn)程拷貝父進(jìn)程的數(shù)據(jù)段、代碼段2.
60、2.進(jìn)程控制進(jìn)程控制- -進(jìn)程的創(chuàng)建進(jìn)程的創(chuàng)建nfork調(diào)用將執(zhí)行兩次返回,它將從父進(jìn)程和子進(jìn)程中調(diào)用將執(zhí)行兩次返回,它將從父進(jìn)程和子進(jìn)程中分別返回。分別返回。n從父進(jìn)程返回時(shí)的返回值為子進(jìn)程的從父進(jìn)程返回時(shí)的返回值為子進(jìn)程的PID,而從子,而從子進(jìn)程返回時(shí)的返回值為進(jìn)程返回時(shí)的返回值為0,并且返回都將執(zhí)行,并且返回都將執(zhí)行fork之之后的語(yǔ)句。調(diào)用出錯(cuò)時(shí),返回值為后的語(yǔ)句。調(diào)用出錯(cuò)時(shí),返回值為-1#include#include#includeint main( ) pid_t pid; pid=fork(); if(pid)0) printf(“fork error!n”); exit(1); else if(pid=
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 建筑施工安全防護(hù)操作合同樣本
- 設(shè)立分公司市場(chǎng)推廣協(xié)議
- 婦科診所主任醫(yī)師招聘協(xié)議范本
- 客戶關(guān)系管理保密協(xié)議管理辦法
- 民事請(qǐng)律師合同范例
- 自主聯(lián)系醫(yī)學(xué)生協(xié)議書(2篇)
- 托管合同法律規(guī)定
- 公路養(yǎng)護(hù)的合同工好嗎
- 工作內(nèi)容 擬寫合同
- 集體建設(shè)用地使用權(quán)聯(lián)營(yíng)合同
- 工會(huì)新聞寫作培訓(xùn)課題
- 統(tǒng)計(jì)年報(bào)和定報(bào)培訓(xùn)
- 小說(shuō)改編權(quán)改編作品轉(zhuǎn)讓合同
- 隧道坍塌應(yīng)急演練
- 物流行業(yè)物流供應(yīng)鏈金融服務(wù)方案
- 浙江省杭州市2023-2024學(xué)年高二上學(xué)期期末學(xué)業(yè)水平測(cè)試政治試題 含解析
- 體育賽事消防應(yīng)急預(yù)案制定
- 腎膿腫護(hù)理查房
- 專題4.3 平面鏡成像【五大題型】【人教版2024】(原卷版)-2024-2025學(xué)年八年級(jí)上冊(cè)物理舉一反三系列(人教版2024)
- 《義務(wù)教育數(shù)學(xué)課程標(biāo)準(zhǔn)(2022年版)》數(shù)學(xué)新課標(biāo)解讀
- 咪咕在線測(cè)評(píng)題
評(píng)論
0/150
提交評(píng)論