色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

Unix C 編程問題精粹

瀏覽:96日期:2024-07-02 17:46:35

文章目錄 第一章:前言 第二章:約定 第三章:開始任務(wù) 第四章:使用lint 第五章:使用make 第六章:優(yōu)質(zhì)無錯編程 第七章:調(diào)試技術(shù) 第八章:其它更好的文檔

第一章:前言

對于C語言,有人認(rèn)為它已經(jīng)落伍了.對于這個問題,仁者見仕,智者見智.的確,C++比C有更強大的諸多優(yōu)勢.但C++是建立在C之上的.這也是Herbert Schildt所著書在全世界暢銷不衰的原因.更何況,要深入學(xué)習(xí)Linux就必需要有相當(dāng)?shù)腃功底.(這也是我搜集整理本文的根由:-) 現(xiàn)結(jié)合個人在編程中的體會,為使新手少走彎路,為老手錦上添花,因此無論你是使用C或C++編程,也無論你是程序設(shè)計的初學(xué)者還是成熟的專業(yè)人員,均會發(fā)現(xiàn),本文將會對你有所收益.當(dāng)然,我盡力寫得清晰易懂,又不古板. 我愛C.(正如世人愛上帝一樣:-)..

第二章:約定

專業(yè)的源程書寫風(fēng)格. 先看看世界級C大師的源程書寫風(fēng)格.如 Steve Maguire 就有許多不錯的建議.

[]倡導(dǎo)使用易于理解的'匈牙利式'的命名約定. 所有的字符變量均以ch開始; 如: char ch_****; 所有的字節(jié)變量均冠以b; 如: byte b_****; 所有的長字變量均冠以l; 如: long l_****; 所有的指針變量均冠以P; 如: char *p_ch_****; 建議類型派生出的基本名字之后加上一個以大寫字母開頭的'標(biāo)簽'.如: 分析 char **ppchMydata; 其讓人一眼就能看出它代表一個指向字符指針Mydata的指針. '匈牙利式'命名的最大不足是難念:-(( .但相對于不是總統(tǒng)演講稿的C源程來說,這又算得了什么?想想看以下的數(shù)據(jù)命名: char a,b,c; long d,e,f; . . . (反正我是不會再看下去了...)

[]倡導(dǎo)規(guī)范書寫. 如果你思如泉涌,而不去也不及顧慮書寫格式,那也沒關(guān)系.在將其交出去之前,用cb命令格式化你的源程.雖然源程的格式不會影響到你編譯結(jié)果的正確性,但切記,能讓其他的程序員能輕松地閱讀它.否則沒人會理你的. 關(guān)于cb命令的更多用法,可以用man cb來參考其手冊頁. 當(dāng)然除了cb之外,還有更多更好的.但cb是你在任何Unix(LINUX)上都找得到的.更何況它并不差.

第三章:開始任務(wù)

開始任務(wù)之前,先做個深呼吸!

[]其他文檔你準(zhǔn)備好了嗎? 你是不是除了C源程之外一無所有了嗎?兵馬未動,糧草先行.你必須先清楚該程序所要完成的功能.在開始寫程序之前,對程序的功能應(yīng)有規(guī)范說明.書寫規(guī)范書和確知程序功能的一個方法是先編寫相應(yīng)的操作手冊.如果你是一人單干,勸你首先寫需求書.切記切記,這對你意味著事半功倍的大好事. 一個實例:我計劃為本行的信貸子功能模塊打一個補丁.我用10周的時間用來寫規(guī)劃書,需求書,操作流程,使用說明等等文檔.之后用2周的時間編寫程序,在初步測試(1周)后遞交給各信貸部門測試使用.然后根據(jù)反饋的信息再更改相應(yīng)文檔,并根據(jù)文檔修改源程.6個月后發(fā)布正式版.

[]一定該遵循ANSI標(biāo)準(zhǔn)嗎? 如果你僅使用ANSI的標(biāo)準(zhǔn)首標(biāo)文件,恭喜你,你的程序有著全世界范圍內(nèi)的廣泛支持和兼容.光明無限.但你必須在通用與專用之間做出取舍,對不起,我?guī)筒涣四? 我的原則是:核心用ANSI,界面按需而取.這樣在轉(zhuǎn)換平臺時僅需另編用戶界面而已.實用至上嘛. 附:ANSI 標(biāo)準(zhǔn)C頭文件

是不是很寒酸?

[]再續(xù)前緣? 在得到新任務(wù)之后并在開始該新任務(wù)之前應(yīng)馬上回想有哪些是曾經(jīng)擁有的.舊調(diào)重彈遠(yuǎn)比另起爐灶來的高效與環(huán)保.

[]是否該有自已的庫? 我的答案是應(yīng)該有自已的特色庫,并與ANSI兼容.與3.8不同的是,你僅需在源程序之后附上自已的專用庫就可以了.其次在有了自已的庫后,源碼會很精煉的.不用去羨慕別人了吧.

[]要學(xué)會條件編譯.注意你的平臺特性.(高手的標(biāo)志?) 除非你確定你要寫的程序是在某特定的OS特定的硬件平臺而量身定做.否則應(yīng)注意數(shù)據(jù)類型的長度,精度都是不同的,不要想當(dāng)然.有時甚至是不同的編譯器的差異都要考慮考慮.

.... ....(歡迎您來充實此處空白) ....

好了,在任務(wù)中,又有哪些細(xì)節(jié)呢?

[]我是不是葛郎臺? 不要那么吝嗇.在源程序中加入詳盡的注釋以使自己和他人即使在許多年以后仍能讀明白它是什么樣的程序. 用注釋行分離各個函數(shù).

[]刪除不需要的代碼時要小心. 一個好建議是:使用#ifdef DEL,而不是簡單地注釋掉甚至是粗暴地直接dd.如果你是使用/* ... */,但一旦要刪除的代碼有很多行,或注釋中以有注釋時,這就可能不那么好使了.

[]如何給源程序文件命名? 表現(xiàn)特色且不與任何原有應(yīng)用名相同.一個簡單地方法就是試試看,系統(tǒng)有什么樣地反應(yīng)?

[]一次只修改一個地方.

[]一次只編寫一個單一功能的函數(shù)。

[]編寫通用程序. 只有當(dāng)程序編寫完,并且完成了所需要的性能要求之后,再反過頭來優(yōu)化該程序.

[]不要使用a.out作為結(jié)果.你大可以使用與源程相同的可執(zhí)行文件名.

[]是否一定要用VI編輯? LINUX下有許多專用編程編輯器.它們能使你有更高的效率和更低的低級輸入錯誤,但我還是要勸你至少要熟練掌握VI.畢竟VI遍地開花.

[]協(xié)同作業(yè).請相信,你不是在孤軍作戰(zhàn).因此,你有必要熟練掌握一些其它的工具.如

.... ....(歡迎您來充實此處空白) ....

第四章:使用lint

lint沒有你想象中的那樣糟糕.相反,一旦源程序形成了沒有LINT錯誤的形式,將很容易保持下去,并享受到如此而帶來的好處.

[]在cc(gcc)之前就應(yīng)使用LINT. lint是一語法檢查程序,對于這個多嘴的婆婆來說,你應(yīng)有足夠的耐心.雖然你知道自已在干什么,但在CC之前使用LINT總是一個好習(xí)慣.

[]lint有哪些特色? 在編譯之前使用lint的重要原因是LINT不但能發(fā)現(xiàn)ANSI C中的語法錯誤,而且也能指出潛在的問題或是難于移植于另一機器的代碼問題.除了能指出簡單語法錯誤之外,LINUT還能基于以下原因指出另外的錯誤: A.無法達(dá)到的語句. B.沒有進入循環(huán). C.沒有被使用的變量. D.函數(shù)參數(shù)從未使用. E.沒有賦值之前自動使用參數(shù). F.函數(shù)在有些地方有返回值,但在其他地方不返回. G.函數(shù)調(diào)用在不同地方使得參數(shù)個數(shù)不同. H.錯誤使用結(jié)構(gòu)指針. I.模糊使用操作符優(yōu)先級. 呵呵呵,挺有用的吧!

[]如何控制LINT的輸出? 有時LINT會有一大屏一大屏的警告信息.但似乎并未指出錯誤.為了找出潛在的錯誤則需費心費力地瀏覽這些大量的警告信息. 但如果你的程序會分出幾個獨立的模塊,在初級啟動LINT時不要用可選項.當(dāng)對這些模塊進行更改或擴充時,可以忽略與代碼無關(guān)的某些警告.為此可用以下選擇項: -h 對判別是否有錯,類型是否正確不給出啟發(fā)式測試. -v 不管函數(shù)中沒有定義的參數(shù) -u 不管被使用的變量和函數(shù)沒有定義或定義了但沒有使用.

[]干脆,在程序中插入指令來影響LINT運行.它看樣子有些像注釋. /*NOTREACHED*/ 不可達(dá)到的代碼不給信息說明. /*VARARGSn*/ 函數(shù)的變量個數(shù)不作通常的檢查,只檢查開始n個參數(shù)的數(shù)據(jù)類型. /*NOSTRUCT*/ 對下一個表達(dá)式不作嚴(yán)格類型檢查. /*ARGUSED*/ 下一函數(shù)中,不給出沒被使用參數(shù)的警告信息. /*LINTLIBRARY*/ 置于文件的開頭,它將不給出沒被使用函數(shù)的警告信息.

關(guān)于LINT的更多用法,請用man lint來獲知.

第五章:使用make

[]什么是make?

Unix(Linux)是一個天生的開發(fā)平臺,我為此感到高興.make是一個強力的工具.它能自動跟蹤相互依賴的源代碼塊并組成一程序,使得很容易建立一可執(zhí)行程序.Make就是這種有依賴關(guān)系的部分和代碼之間所作的規(guī)格說明.

[] 所有的程序都要使用make? 是的.盡管你只有幾個簡單的模塊,但你需要有一種結(jié)構(gòu)來支持它從簡單走向復(fù)雜.除非你的程序已經(jīng)蓋棺定論.

[]Makefile由哪些組成? Makefile由以下幾個部分組成:

注釋. ^^^^ 使用#符號插入.make將忽略#之后的任何內(nèi)容以及其后的RETURN鍵.

變量. ^^^^ make允許定義與SHELL變量類似的有名變量.比如,你定義了SOURCES=prog.c,那么該變量的值$(SCOURES)就包含了源文件名.

依賴關(guān)系. ^^^^^^^^ 左邊是目標(biāo)模塊,后接一冒號.再接與該模塊有依賴關(guān)系的模塊.

命令. ^^^^ 以TAB鍵開始(即使用相同數(shù)量的空格也不能代替它).

[]Makefile示例 下面介紹一個簡單的示例來說明make的用法.假設(shè)你的程序有兩個源文件main.c和myc.c,一個位於子目錄include下的頭文件myhead.h,一個庫由三個源文件myrout1.c,myrout2.c,myrout3.c產(chǎn)生. 其makefile文件為: #一個基本的MAKEFILE文件. #其中包括個人的頭文件和個人庫. HEADERS=include/myhead.h SOURCES=main.c myc.c PRODUCT=$(HOME)/bin/tool LIB=myrout.a LIBSOURES=myrout1.c myrout2.c myrout3.c CC=cc CFLAGS=-g all:$(PRODUCT) $(PRODUCT):$(SOURCES) $(CC)$(CFLAGS) -o $(PRODUCT)$(SOURCES) lint:$(PRODUCT) lint $(SOURCES)$(LIBSOURCES) 哈哈,挺象SHELL編程的.如果你與我一樣使用LINUX下的gcc,那么只要把上面的CC=cc改為CC=gcc即可.怎么樣,想來一個更復(fù)雜點的嗎?

[]一個更為復(fù)雜的Makefile 你是否注意到,在上例中,只要啟動make,就會重新編譯所有源代碼. 如果你能看懂以下的makefile,恭喜恭喜,你通關(guān)了. #一個更為復(fù)雜的makefile HEADERS=include/myhead.h SOURES=main.c myc.c OBJECTS=main.c myc.c PRODUCT=$(HOME)/bin/tool LIB=myrout.a LIBSOURCES=myrout1.c myrout2.c myrout3.c LIBOBJECTS=$(LIB)(myrout1.o)$(LIB)(myrout2.o)$(LIB)(myrout3.o) INCLUDE=include CC=cc CFLAGS=-g -Xc LINT=lint LINTFLAGS=-Xc all:$(PRODUCT) $(PRODUCT):$(OBJECTS)$(LIB) $(CC)(CFLAGS)-o$(PRODUCT)$(OBJECTS)$(LIB) .c.o: $(HEADERS) $(CC)$(CFLAGS) -c I$(INCLUDE)$< $(LIB):$(HEADERS)$(LIBSOURCES) $(CC) $(CFLAGS) -c $(?:.o=.c) ar rv $(LIB) $? rm $? .c.c:; lint: $(PRODUCT) $(LINT)$(LINIFLAGS)$(SOURCES)$LIBSOURCES)

第六章:優(yōu)質(zhì)無錯編程

親愛的,檢查一下,你是否注意到了以下的細(xì)節(jié)?也就是說,你是否是一個合格的,能編寫優(yōu)質(zhì)無錯代碼的程序員?要永遠(yuǎn)記住,編寫無錯代碼是程序員的責(zé)任,而不是測試員.(摘錄于本人的'細(xì)節(jié)頁',因此本節(jié)將永遠(yuǎn)不會保持完整,歡迎您來充實她)

[]所有程序員至少出現(xiàn)過的一個錯誤: if(a=3){......}如果a等于3,那么...... 你至少要養(yǎng)成這樣的習(xí)慣:當(dāng)判斷一個變量與一個常量是否相等時,將常量寫在前面.這樣即使你一不小心寫成這樣:if(3=a){......}在cc 之前就可以很容易發(fā)現(xiàn)它.

[]老調(diào)重彈:邏輯操作符的優(yōu)先權(quán). 我不愿多嘴.總之,如果你一定要編寫如下代碼時: if(a&0x1&&b&0x2){......} 你的手頭最好有一本詳盡的指南.或者你是這方面的專家.

[]盡量不使用int數(shù)據(jù)類型. 這僅是一個忠告.你大可使用char,short,long數(shù)據(jù)類型.若干年以后,當(dāng)你成長為高手之時,你會發(fā)現(xiàn)此時我的良苦用心.

[]對于非整型函數(shù)一定要完整定義. 如 long float jisuan(char chArr[],int chNum) { long float lMydata; ... ... return(lMydata); }

[]對于非整型函數(shù)的輸入要當(dāng)心. 如 long float lfNum; ... ... scanf('%lf',&lfNum);

[]float 型的有效數(shù)字為7位.當(dāng)多于7位時,第8位及以后的位將不準(zhǔn)確,可以將其定義為long float型.

[]文件的輸入出盡量采用fread fwrite函數(shù).只有當(dāng)另有用途時才用fprintf fscanf 函數(shù).

[]對于數(shù)組及字符串的比較操作時要確認(rèn)以''結(jié)束.

第七章:調(diào)試技術(shù)

調(diào)試技術(shù)在本文中不太好說,之所以將其獨立成章是想套用M$的老話:'在下一版本中將會做得更好':-((.其實這類文章在全國各大BBS上滿天飛.

在此我只想說說程序員的應(yīng)盡職責(zé)之一:在程序中使用斷言. ~~~~ []既要維護程序的交付版本,又要維護程序的調(diào)試版本,這時可以利用斷言補救.

[]要使用斷言對函數(shù)參數(shù)進行確認(rèn).

[]要從程序中刪除無定義的特性,或者在程序中使用斷言來檢查出無定義特性的非法使用.

[]不要浪費別人的時間,詳細(xì)說明不清楚的斷言.

[]消除所做的隱式假定,或者利用斷言檢查其正確性.

[]利用斷言來檢查不可能發(fā)生的情況.

一個實例:我在我的源程序中都使用斷言.在本人所編制的全國電子匯兌模糊檢索功能模塊測試中,前臺人員氣喘吁吁地告訴我,屏幕上出現(xiàn)了不認(rèn)識的英文.我說最前面的是哪幾個數(shù)字,然后根據(jù)此數(shù)字查閱斷言文檔,原來是前日日終未正常結(jié)束,經(jīng)查只有半個庫.這種情況極少發(fā)生,但不是不可能發(fā)生.使用斷言能及時正確地判別是否是程序的錯誤還是外部的因素.因此使用斷言,是將錯誤消滅在發(fā)生錯誤之前的一個極其重要的手法.這也是判斷一個程序員是否具備良好素質(zhì)的一個方面.

標(biāo)簽: Unix系統(tǒng)
主站蜘蛛池模板: 一区二区三区免费在线视频 | 日韩精品在线一区二区 | 亚洲欧美日韩综合一区久久 | 亚洲欧美一区二区久久香蕉 | 国产欧美日韩在线人成aaaa | 欧美三级视频在线观看 | 久久久久久九九 | 欧美日韩高清不卡一区二区三区 | 亚洲三级在线看 | 免费一级毛片女人图片 | 久久精品女人毛片国产 | 美女操男人 | 99re6热视频精品免费观看 | 亚洲国产成人久久综合一区77 | 日本一本黄| 国产精品性视频免费播放 | 台湾香港澳门三级在线 | 一区二区三区四区在线免费观看 | 操美国女人 | 亚洲成a v人片在线看片 | 日本韩国一级 | 久久国产成人亚洲精品影院老金 | 久草免费看 | 日韩专区欧美 | 亚洲三级在线观看 | 日本一区二区三区国产 | 91精品欧美综合在线观看 | 日韩精品免费看 | 日本久久一区二区 | 成年女人毛片免费观看97 | 国产精品在线播放 | 日本不卡高清免费 | 久久久久久久久久久大尺度免费视频 | 欧美一区二区aa大片 | 国产精品欧美一区二区 | 国内外成人免费在线视频 | 好妞操| 又黄又免费的网站 | 特级黄色毛片在放 | 免费在线一区二区三区 | 精品久久久久久中文字幕 |