第一篇:《軟件項(xiàng)目管理方法與實(shí)踐》課程設(shè)計(jì)報(bào)告
軟件項(xiàng)目管理方法與實(shí)踐 課 程 設(shè) 計(jì) 報(bào) 告
1006602-** ***
一、設(shè)計(jì)時(shí)間
2013年12月23日-----1月6日
二、設(shè)計(jì)地點(diǎn)
湖南城市學(xué)院信息樓406機(jī)房
三、設(shè)計(jì)目的1,2,3,四、設(shè)計(jì)小組成員
五、指導(dǎo)老師
陽(yáng)王東老師、費(fèi)雄偉老師
六、設(shè)計(jì)課題
七、基本思路及關(guān)鍵問(wèn)題的解決方法
八、流程圖
九、調(diào)試過(guò)程中出現(xiàn)的問(wèn)題及相應(yīng)解決辦法
十、課程設(shè)計(jì)心得體會(huì)
十一、源程序
參考文獻(xiàn)
第二篇:課程設(shè)計(jì)項(xiàng)目實(shí)踐
項(xiàng)目實(shí)踐、設(shè)計(jì)與產(chǎn)品制作
本專題實(shí)踐是專為電氣工程專業(yè)的高年級(jí)學(xué)生,進(jìn)入專業(yè)學(xué)習(xí)前所進(jìn)行的專題培訓(xùn),目的是為了更好地使學(xué)生適應(yīng)專業(yè)學(xué)習(xí)和畢業(yè)設(shè)計(jì),重點(diǎn)培養(yǎng)同學(xué)們動(dòng)手實(shí)踐和自我規(guī)劃課題的能力。
專業(yè)專題實(shí)踐分硬件和軟件兩類。其中硬件類實(shí)踐是在微機(jī)原理與應(yīng)用、單片機(jī)、DSP等課程基礎(chǔ)上,結(jié)合實(shí)際的小項(xiàng)目,通過(guò)項(xiàng)目調(diào)研、方案設(shè)計(jì)、實(shí)驗(yàn)調(diào)試、總結(jié)報(bào)告,進(jìn)行具體項(xiàng)目的綜合訓(xùn)練。在整個(gè)實(shí)踐過(guò)程中,希望同學(xué)們有意識(shí)地注意以下幾個(gè)方面的訓(xùn)練:調(diào)研,方案設(shè)計(jì),系統(tǒng),控制軟件方法設(shè)計(jì),調(diào)試,總結(jié)。
同學(xué)們首先要站在宏觀角度審視一個(gè)具體項(xiàng)目,通過(guò)調(diào)研,制定技術(shù)方案;然后按照所確定的技術(shù)路線進(jìn)行相應(yīng)的設(shè)計(jì)、制作、編程、調(diào)試和測(cè)試,最后進(jìn)行總結(jié)和提高。希望同學(xué)們以非常認(rèn)真的態(tài)度,珍惜難得的實(shí)踐機(jī)會(huì),認(rèn)真完成實(shí)踐任務(wù)。
需要提醒的是,專業(yè)專題實(shí)踐不同于其它課程,它是項(xiàng)目型教學(xué),主要是發(fā)揮同學(xué)們自己的主觀能動(dòng)性,自主學(xué)習(xí)性,不要依賴教師。在實(shí)踐中教師是在宏觀上輔導(dǎo)(如幫助分析方案和解答疑惑問(wèn)題),所起的作用是輔助性的。更多的是需要靠同學(xué)們自己主動(dòng)去調(diào)研、設(shè)計(jì)方案、實(shí)驗(yàn)、總結(jié)。項(xiàng)目型實(shí)踐課程與平時(shí)的實(shí)驗(yàn)課不同,實(shí)驗(yàn)課有詳細(xì)、具體的實(shí)驗(yàn)指導(dǎo)書(shū),告訴同學(xué)們具體的實(shí)驗(yàn)步驟。項(xiàng)目實(shí)踐課并不給出具體詳細(xì)實(shí)踐步驟和方法,需要同學(xué)們自己通過(guò)調(diào)研、與老師或同學(xué)討論、合理分工完成。這里不僅培養(yǎng)同學(xué)們的自主學(xué)習(xí)(自主研發(fā))精神和能力,也培養(yǎng)大家主動(dòng)型的學(xué)習(xí)習(xí)慣,同時(shí)更是培養(yǎng)大家相互協(xié)作精神、發(fā)現(xiàn)問(wèn)題和解決問(wèn)題的能力以及研究性學(xué)習(xí)的能力。
一、實(shí)踐要求
1. 每個(gè)實(shí)驗(yàn)項(xiàng)目3人一組,分工進(jìn)行,提倡好的合作精神; 2. 專題實(shí)踐以設(shè)計(jì)、實(shí)踐為主,共四周時(shí)間;
3. 愛(ài)護(hù)設(shè)備,不隨意更換設(shè)備,如有要求,請(qǐng)與老師聯(lián)系;
4. 做硬件實(shí)驗(yàn)時(shí),注意斷電操作,即所有的接線、改線及拆線操作均應(yīng)在不帶電的狀態(tài)下進(jìn)行,嚴(yán)禁帶電操作;
5. 堅(jiān)持復(fù)查制度,例如通電前的復(fù)查:一人接線另一人檢查,重要結(jié)果和現(xiàn)象復(fù)查實(shí)行二人制;
6. 每天實(shí)驗(yàn)完畢(包括中午),請(qǐng)恢復(fù)桌椅原位,保持實(shí)驗(yàn)室的整潔,關(guān)閉所用實(shí)驗(yàn)設(shè)備電源,再離開(kāi)實(shí)驗(yàn)室;
7. 注意人身、實(shí)驗(yàn)儀器和設(shè)備安全,防止發(fā)生事故。萬(wàn)一發(fā)生事故,應(yīng)立即切斷電源,保護(hù)人員,保存現(xiàn)場(chǎng),并立即向教師報(bào)告,檢查事故原因,總結(jié)并吸取教訓(xùn);
8. 電熱設(shè)備(如烙鐵)用畢必須隨手拔下電源插頭,以免過(guò)熱引起火災(zāi);平時(shí)注意實(shí)驗(yàn)板上的帶電情況,測(cè)量和調(diào)試中防止觸電、短路;注意示波器高頻探頭的地極是通過(guò)示波器電源插頭的中心端接地的,切勿將該地極與交流電源的火線相接,否則將發(fā)生短路事故;
9. 參考文獻(xiàn)或芯片、器件手冊(cè)閱讀量要求:20篇以上; 10. 要求每日記錄工作日志和實(shí)驗(yàn)情況,參見(jiàn)簡(jiǎn)要工作日志格式。
二、實(shí)踐報(bào)告及成績(jī)?cè)u(píng)定
1. 以小組(3人名義)形式需要完成3份報(bào)告:(1)開(kāi)題報(bào)告;(2)中期報(bào)告;(3)結(jié)題報(bào)告。報(bào)告要求見(jiàn)后面要求。注意:
2. 每人需要完成1份個(gè)人小結(jié),第5周五前前提交,延期扣分。報(bào)告格式見(jiàn)后面要求。3. 實(shí)施2次檢查,(1)中期檢查,第2周周5;(2)結(jié)題檢查,第4周周5。4. 成績(jī)?cè)u(píng)定依據(jù):
開(kāi)題10分;中期考核10分;態(tài)度10分; 項(xiàng)目工作完成情況40分:
項(xiàng)目完成的質(zhì)和量是考核的重點(diǎn),還要考核同學(xué)們專題實(shí)踐的主動(dòng)性,項(xiàng)目組成員之間的合作情況,儀器設(shè)備、芯片的正確使用情況,項(xiàng)目驗(yàn)收時(shí)匯報(bào)和答辯情況等; 項(xiàng)目報(bào)告30分:
報(bào)告質(zhì)量情況、總結(jié)的深度是考核的重點(diǎn),兼顧認(rèn)真程度和格式等。建議結(jié)題報(bào)告按學(xué)位論文格式完成,要求有:摘要、綜述(文獻(xiàn)閱讀、任務(wù)分析、工作安排等)、正文論述、項(xiàng)目結(jié)論、參考文獻(xiàn)等。
鼓勵(lì)同學(xué)們自主創(chuàng)新,如有專利、論文等的思路或草稿,可以考慮適當(dāng)加分。
.結(jié)題報(bào)告格式(每組只交一份,第2周末交)要求按畢業(yè)設(shè)計(jì)論文模板書(shū)寫(xiě)結(jié)題報(bào)告。報(bào)告包括以下內(nèi)容: 1. 報(bào)告摘要;
2. 課題論述:包括專題實(shí)驗(yàn)?zāi)康?,文獻(xiàn)閱讀、項(xiàng)目的綜述,項(xiàng)目要求、技術(shù)要點(diǎn)、難點(diǎn);
3. 設(shè)計(jì)方案說(shuō)明,包括設(shè)計(jì)方案研究、分析、總體方案思路,所采取的技術(shù)路線,工作和時(shí)間安排,人員分工;
4. 設(shè)計(jì)內(nèi)容,包括具體的項(xiàng)目設(shè)計(jì),軟硬件設(shè)計(jì),調(diào)試,討論;
資源:?jiǎn)纹瑱C(jī)的選擇論述,軟件資源的利用等; 硬件:電路原理圖、PCB圖(如果有的話); 軟件:結(jié)構(gòu)、流程、源程序和程序注釋; 調(diào)試:調(diào)試過(guò)程、問(wèn)題的發(fā)現(xiàn)和解決;
5. 課題實(shí)驗(yàn)、調(diào)試記錄,完成情況,存在問(wèn)題及可能的解決方案,工作總結(jié); 6. 項(xiàng)目結(jié)論(實(shí)驗(yàn)結(jié)果和結(jié)論、成果、遺憾、后續(xù)工作);
7. 附錄(包括列出所用軟件工具、找到的各種電子參考資料、參考文獻(xiàn)等)
個(gè)人實(shí)踐小結(jié)(每人交一份),第2周末交
主要寫(xiě)個(gè)人對(duì)項(xiàng)目的理解、投入、貢獻(xiàn)、收獲,并對(duì)自己的項(xiàng)目工作做簡(jiǎn)單評(píng)估,按五個(gè)等級(jí)自評(píng):優(yōu)(90~100),良(80~89),中(79~70),及格(60~69),差(60以下)。請(qǐng)實(shí)事求是評(píng)價(jià)個(gè)人工作,過(guò)高或過(guò)低評(píng)價(jià)都不推薦。
項(xiàng)目1 微機(jī)繼電保護(hù)的設(shè)計(jì)與實(shí)現(xiàn)
一.實(shí)驗(yàn)?zāi)康?/p>
學(xué)習(xí)和實(shí)踐交流信號(hào)數(shù)據(jù)采集和微機(jī)保護(hù)算法,學(xué)習(xí)微機(jī)保護(hù)的軟、硬件原理,設(shè)計(jì)微機(jī)保護(hù)原理型樣機(jī),使用學(xué)?,F(xiàn)有單片機(jī)教學(xué)實(shí)驗(yàn)箱或?qū)嶒?yàn)板完成原理型微機(jī)繼電保護(hù)裝置并實(shí)現(xiàn)其主要功能。
二.實(shí)驗(yàn)任務(wù)
1. 學(xué)習(xí)一種單片機(jī)(如Intel8051、MC、ARM、瑞薩9等)或DSP(2407、2812、28335等)原理和使用,學(xué)習(xí)其編程方法;
2. 學(xué)習(xí)A/D轉(zhuǎn)換技術(shù),搭建單片機(jī)外圍模擬交流信號(hào)(A/D轉(zhuǎn)換器外圍信號(hào))采集環(huán)節(jié),用信號(hào)發(fā)生器模擬繼電保護(hù)電流信號(hào)(互感器輸出),測(cè)試瞬時(shí)性繼電保護(hù)(如電流速斷)動(dòng)作特性(動(dòng)作和返回,返回系數(shù)0.9); 3. 設(shè)計(jì)交流信號(hào)的數(shù)據(jù)采集和微機(jī)保護(hù)算法,設(shè)計(jì)數(shù)字濾波算法,編寫(xiě)繼電保護(hù)軟件,常用有效值算法,例如半周波積分算法、差分算法、傅立葉算法等;
4. 編寫(xiě)實(shí)時(shí)顯示程序,實(shí)現(xiàn)顯示功能:顯示交流信號(hào)有效值(折算出虛擬CT原邊電流,例如100/5A,5A/2V),如能設(shè)計(jì)通訊,使用PC機(jī)做上位監(jiān)控計(jì)算機(jī)實(shí)時(shí)顯示測(cè)量值最好;
5. 編寫(xiě)延時(shí)過(guò)電流保護(hù)邏輯的微機(jī)保護(hù)軟件,并實(shí)現(xiàn)延時(shí)過(guò)電流保護(hù); 6. 設(shè)計(jì)實(shí)驗(yàn)電路板(原理圖和PCB電路板),并評(píng)估。
三.相關(guān)資料和實(shí)驗(yàn)平臺(tái)
1. 單片機(jī)或DSP實(shí)驗(yàn)主板,單片機(jī)或DSP資料和datasheet; 2. 繼電保護(hù)、微機(jī)繼電保護(hù)參考書(shū);
3. 微機(jī)繼電保護(hù)參考文獻(xiàn),軟件流程和交流采樣算法文獻(xiàn); 4. 實(shí)驗(yàn)板、部分外圍芯片(如運(yùn)放)、信號(hào)發(fā)生器、示波器等 5. C++編程或Lab View界面編程語(yǔ)言。
四.提示
請(qǐng)同學(xué)編寫(xiě)繼電保護(hù)軟件,主要是設(shè)計(jì)交流數(shù)據(jù)采集策略和算法,讓單片機(jī)實(shí)時(shí)顯示被采集的交流信號(hào)有效值,比較保護(hù)定值,決定保護(hù)動(dòng)作(驅(qū)動(dòng)指示燈實(shí)時(shí)點(diǎn)亮)。
五.選題對(duì)象
限已經(jīng)選修數(shù)字和模擬電子電路、單片機(jī)課程的同學(xué),學(xué)習(xí)過(guò)微機(jī)繼電保護(hù)最好。3人一組,合理分工。
項(xiàng)目2 變頻器的設(shè)計(jì)與實(shí)現(xiàn)
暫緩
一、實(shí)驗(yàn)?zāi)康?/p>
學(xué)習(xí)變頻調(diào)速原理,學(xué)習(xí)正弦波PWM控制方法,掌握設(shè)計(jì)和實(shí)現(xiàn)變頻調(diào)試器的方法。本任務(wù)擬采用紙上談兵方式進(jìn)行,主要是考核同學(xué)們具體任務(wù)的分析問(wèn)題和解決問(wèn)題的能力。要求給出設(shè)計(jì)方案、方法、作出設(shè)計(jì)、以及實(shí)現(xiàn)方式。
二.實(shí)驗(yàn)任務(wù)
1. 利用IPM設(shè)計(jì)變頻器的主電路;
2. 利用瑞薩單片機(jī)、MSP430或DSP設(shè)計(jì)變頻器的控制系統(tǒng)(主要是PWM); 3. 調(diào)試變頻器的軟、硬件系統(tǒng),最終能帶三相小型異步電機(jī);
4. 設(shè)計(jì)相關(guān)的控制算法、控制軟件,產(chǎn)生變頻PWM信號(hào)或功率輸出,實(shí)現(xiàn):
(1)變頻器的變頻輸出、V/F特性(V/F=const);
(2)電機(jī)的起動(dòng)和停止特性、電機(jī)運(yùn)行中的變頻控制、調(diào)壓控制等;(3)評(píng)估逆變器輸出波形。
三.實(shí)驗(yàn)平臺(tái)和有關(guān)資料
1. 變頻器樣機(jī)(供設(shè)計(jì)參考,該樣機(jī)資料有限,開(kāi)放性較差,能開(kāi)發(fā)的余地?。?; 2. 提供變頻器主電路板及相關(guān)器件,可在此基礎(chǔ)上完成變頻器主電路系統(tǒng);
3. 自選單片機(jī)(實(shí)驗(yàn)室已有的)做控制平臺(tái),依據(jù)該單片機(jī)Datasheet編寫(xiě)相關(guān)控制軟件并調(diào)試;
4. 相關(guān)的一些網(wǎng)站:TI公司 DSP網(wǎng)站上面有許多介紹變頻器控制的軟件、方法、甚至源代碼;三菱公司網(wǎng)站,介紹IPM模塊、整流模塊;
一些變頻器網(wǎng)站介紹變頻器:如http://004km.cn等; 5. 圖書(shū)館可借閱一些變頻器相關(guān)書(shū)籍、文獻(xiàn)。
四.選題對(duì)象
限已經(jīng)選修過(guò)電力電子、數(shù)字和模擬電子電路、單片機(jī)課程的同學(xué)。
第三篇:華中科技大學(xué)軟件課程設(shè)計(jì)報(bào)告
軟件課程設(shè)計(jì)報(bào)告
班 級(jí):姓 名:學(xué) 號(hào):
光 信0 8 0 4 廖 娟
U 2 0 0 8 1 3 1 9 7 光信0804廖娟
U200813197
目 錄 軟件設(shè)計(jì)............................................4
1.1 設(shè)計(jì)題目及目的.................................4 1.2 設(shè)計(jì)思想.......................................4 1.3 背景知識(shí).......................................4(1).定義:.....................................4(2).存儲(chǔ)結(jié)構(gòu):.................................5(3).遍歷二叉樹(shù):...............................6 1.4 程序結(jié)構(gòu)及功能劃分.............................7(1).廖娟#注釋.cpp..............................7(2).廖娟#軟件課程設(shè)計(jì).cpp......................8 1.5 程序流程......................................10 2 軟件測(cè)試...........................................14
2.1 測(cè)試環(huán)境......................................14 2.2 廖娟#注釋.cpp 的測(cè)試過(guò)程.......................14 2.3 廖娟#軟件課程設(shè)計(jì).cpp 的測(cè)試過(guò)程...............15(1).程序運(yùn)行前的初始界面.......................15(2).輸入數(shù)據(jù)及二叉樹(shù)打印的畫(huà)面.................16(3).選擇操作的提示畫(huà)面.........................16(4).程序測(cè)試時(shí)的畫(huà)面..........................17 3 算法改進(jìn)...........................................19
3.1問(wèn)題發(fā)現(xiàn)......................................19 軟件課程設(shè)計(jì)
2010年1月
(1).問(wèn)題一:..................................20(2).問(wèn)題二:.................................21 3.2解決方案......................................21(1).問(wèn)題一改進(jìn)方案:.........................21(2).問(wèn)題二改進(jìn)方案:.........................22 4 開(kāi)發(fā)體會(huì)...........................................23 附錄:源代碼清單......................................25
廖娟#注釋.cpp.....................................25 廖娟#軟件課程設(shè)計(jì).cpp.............................29 參考文獻(xiàn).............................................35 光信0804廖娟
U200813197軟件設(shè)計(jì)
1.1 設(shè)計(jì)題目及目的
設(shè)計(jì)題目:二叉樹(shù)的查找--用鏈表結(jié)構(gòu)實(shí)現(xiàn)二叉樹(shù)建立、查詢、打印的源程序。
設(shè)計(jì)目的:基于C語(yǔ)言的基礎(chǔ),熟練運(yùn)用結(jié)構(gòu)體等擴(kuò)展數(shù)據(jù)手段,定義應(yīng)用數(shù)據(jù)、并進(jìn)行運(yùn)用。本題要求掌握數(shù)據(jù)的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu),并編程實(shí)踐它們的實(shí)現(xiàn)、應(yīng)用方法。
1.2 設(shè)計(jì)思想
利用結(jié)構(gòu)體,鏈表等數(shù)據(jù)結(jié)構(gòu),以及折半查找、選擇排序等基本算法,結(jié)合指針,文件等相關(guān)知識(shí),利用C語(yǔ)言編寫(xiě)鏈?zhǔn)浇Y(jié)構(gòu)實(shí)現(xiàn)二叉樹(shù)的建立、打印、查詢、先序遍歷、中序遍歷、后序遍歷等基本功能,并將這些功能用獨(dú)立的子函數(shù)實(shí)現(xiàn),通過(guò)主函數(shù)的調(diào)用實(shí)現(xiàn)相應(yīng)的功能。
1.3 背景知識(shí)
(1).定義:
二叉樹(shù)是由n(n>=0)個(gè)結(jié)點(diǎn)的有限集合構(gòu)成,此集合或者為空集,或者由一個(gè)根結(jié)點(diǎn)及兩棵互不相交的左右子樹(shù)組成,并且左右子樹(shù)都是二叉樹(shù)。
這也是一個(gè)遞歸定義。二叉樹(shù)可以是空集合,二叉樹(shù)結(jié)點(diǎn)的子樹(shù) 軟件課程設(shè)計(jì)
2010年1月
要區(qū)分左子樹(shù)和右子樹(shù),即使只有一棵子樹(shù)也要進(jìn)行區(qū)分,說(shuō)明它是左子樹(shù),還是右子樹(shù)。二叉樹(shù)的定義方法:
Struct tree { char info;struct tree *left, *right;
}(2).存儲(chǔ)結(jié)構(gòu):
存儲(chǔ)結(jié)構(gòu)分為順序存儲(chǔ)結(jié)構(gòu)和鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。
a.順序存儲(chǔ)結(jié)構(gòu):從樹(shù)根起,自上層至下層,每層自左至右的給所有結(jié)點(diǎn)編號(hào)缺點(diǎn)是有可能對(duì)存儲(chǔ)空間造成極大的浪費(fèi),在最壞的情況下,一個(gè)深度為H且只有H個(gè)結(jié)點(diǎn)的右單支樹(shù)確需要2h-1個(gè)結(jié)點(diǎn)存儲(chǔ)空間。而且,若經(jīng)常需要插入與刪除樹(shù)中結(jié)點(diǎn)時(shí),順序存儲(chǔ)方式不是很好!光信0804廖娟
U200813197
b.鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu):
存儲(chǔ)二叉樹(shù)經(jīng)常用二叉鏈表法
(3).遍歷二叉樹(shù):
假如以L、D、R分別表示遍歷左子樹(shù)、遍歷根結(jié)點(diǎn)和遍歷右子樹(shù),遍歷整個(gè)二叉樹(shù)則有DLR、LDR、LRD、DRL、RDL、RLD六種遍歷方案。若規(guī)定先左后右,則只有前三種情況,分別規(guī)定為:
DLR——先(根)序遍歷,LDR——中(根)序遍歷,軟件課程設(shè)計(jì)
2010年1月
LRD——后(根)序遍歷。①.先序遍歷二叉樹(shù)的操作定義為: 若二叉樹(shù)為空,則空操作;否則 A.訪問(wèn)根結(jié)點(diǎn); B.先序遍歷左子樹(shù); C.先序遍歷右子樹(shù)。
②.中序遍歷二叉樹(shù)的操作定義為: 若二叉樹(shù)為空,則空操作;否則 A.中序遍歷左子樹(shù); B.訪問(wèn)根結(jié)點(diǎn); C.中序遍歷右子樹(shù)。
③.后序遍歷二叉樹(shù)的操作定義為: 若二叉樹(shù)為空,則空操作;否則 A.后序遍歷左子樹(shù); B.后序遍歷右子樹(shù); C.訪問(wèn)根結(jié)點(diǎn)。
1.4 程序結(jié)構(gòu)及功能劃分
(1).廖娟#注釋.cpp
主要分為主函數(shù)、創(chuàng)建二叉樹(shù)子函數(shù)、二叉樹(shù)查詢子函數(shù)、二叉樹(shù)打印子函數(shù)四個(gè)部分。其基本功能分塊,如下圖所示: 光信0804廖娟
U200813197
(2).廖娟#軟件課程設(shè)計(jì).cpp 在 廖娟#注釋.cpp 的基礎(chǔ)上進(jìn)行了一些算法改進(jìn),進(jìn)行了簡(jiǎn)單的界面設(shè)計(jì),能夠?qū)崿F(xiàn)友好的交互,系統(tǒng)用戶進(jìn)入界面控制后,對(duì)不同的功能操作提示不同,此外加入了二叉排序樹(shù)的前序遍歷程序、中序遍歷程序和后序遍歷程序。
①.先序遍歷源代碼:
void PreorderTraversal(struct tree *root){ if(root==0)return;printf(“%c”,root->info);軟件課程設(shè)計(jì)
2010年1月
PreorderTraversal(root->left);PreorderTraversal(root->right);} ②.中序遍歷源代碼:
void InorderTraversal(struct tree *root){ if(!root)return;InorderTraversal(root->left);printf(“%c”,root->info);InorderTraversal(root->right);} ③.后序遍歷源代碼:
void PostorderTraversal(struct tree *root){ if(!root)return;PostorderTraversal(root->left);PostorderTraversal(root->right);printf(“%c”,root->info);} 光信0804廖娟
U200813197
1.5 程序流程
廖娟#注釋.cpp的主程序的流程圖如下: 軟件課程設(shè)計(jì)
2010年1月
創(chuàng)建二叉樹(shù)的流程圖如下: 光信0804廖娟
U200813197
二叉樹(shù)查詢的流程圖如下: 軟件課程設(shè)計(jì)
2010年1月
二叉樹(shù)打印的流程圖如下: 光信0804廖娟
U200813197軟件測(cè)試
2.1 測(cè)試環(huán)境
Microsoft Visual C++
2.2 廖娟#注釋.cpp 的測(cè)試過(guò)程
但是在測(cè)試的過(guò)程中也發(fā)現(xiàn)了一些問(wèn)題,設(shè)計(jì)示例給出的源代碼中存在幾個(gè)問(wèn)題在下圖所示操作中暴露出來(lái)了:軟件課程設(shè)計(jì)
2010年1月
具體的解決方案見(jiàn)算法改進(jìn)。
2.3 廖娟#軟件課程設(shè)計(jì).cpp 的測(cè)試過(guò)程
輸入50個(gè)數(shù)字(或字母),對(duì) 廖娟#軟件課程設(shè)計(jì).cpp 進(jìn)行測(cè)試。(1).程序運(yùn)行前的初始界面 光信0804廖娟
U200813197
(2).輸入數(shù)據(jù)及二叉樹(shù)打印的畫(huà)面
(3).選擇操作的提示畫(huà)面 軟件課程設(shè)計(jì)
2010年1月
(4).程序測(cè)試時(shí)的畫(huà)面
①.選擇1,進(jìn)行先序遍歷; ②.選擇2,進(jìn)行中序遍歷; ③.選擇3,進(jìn)行后序遍歷;
④.選擇4,進(jìn)行查詢結(jié)點(diǎn),再輸入要查詢的結(jié)點(diǎn)e,找到了,輸出:
Successful search!!key=e
繼續(xù)輸入w,同樣查詢成功; ⑤.輸入m,沒(méi)找到,輸出結(jié)果:
Search Failure!!光信0804廖娟
U200813197
⑥.再次選擇3,進(jìn)行后序遍歷,與③輸出相同;
再次選擇2,進(jìn)行中序遍歷,與②輸出相同; ⑦.再次選擇4,進(jìn)行查詢結(jié)點(diǎn),運(yùn)行結(jié)果正常; ⑧.再次選擇1,進(jìn)行先序遍歷,與①輸出相同; ⑨.選擇8,輸入錯(cuò)誤,沒(méi)有對(duì)應(yīng)的操作,輸出:
您 的 輸 入 有 誤,請(qǐng) 重 新 輸 入!!⑩.選擇5,進(jìn)行退出操作,輸出:
光 信 0 8 0 4 ———— 廖 娟0 1 0 年 1 月軟件課程設(shè)計(jì)
2010年1月算法改進(jìn)
3.1問(wèn)題發(fā)現(xiàn)
在完成第4項(xiàng)選做項(xiàng)目時(shí),程序前面部分的創(chuàng)建、查詢、打印二叉樹(shù)的算法仍采用已給出的設(shè)計(jì)示例中的算法,但是在測(cè)試過(guò)程中發(fā)現(xiàn)存在問(wèn)題。光信0804廖娟
U200813197
(1).問(wèn)題一:
第一次先序遍歷的輸出結(jié)果為:edaf
第二次先序遍歷的輸出結(jié)果為:f 經(jīng)過(guò)觀察及調(diào)試發(fā)現(xiàn)問(wèn)題在于查詢二叉樹(shù)子函數(shù),其中root是根結(jié)點(diǎn),運(yùn)行查詢后root就被移動(dòng)了,所以再次要求先序遍歷的結(jié)果就與第一次先序遍歷的結(jié)果不同。
未改動(dòng)前源代碼如下: 軟件課程設(shè)計(jì)
2010年1月
(2).問(wèn)題二:
設(shè)計(jì)示例中給出的函數(shù)運(yùn)行后,沒(méi)有退出的方式,即沒(méi)有出口,程序無(wú)法正常退出。
3.2解決方案
(1).問(wèn)題一改進(jìn)方案:
函數(shù)內(nèi)部定義一個(gè)指針tree *t,用 *t指向根結(jié)點(diǎn),這樣進(jìn)行查詢操作后根結(jié)點(diǎn)就不會(huì)移動(dòng)了。
改動(dòng)后源代碼如下: 光信0804廖娟
U200813197
(2).問(wèn)題二改進(jìn)方案:
在switch語(yǔ)句中增加:
case 5:
printf(“
光 信 0 8 0 4 ———— 廖 娟nn”);printf(“ 0 1 0 年 1 月nn”);return;來(lái)實(shí)現(xiàn)退出程序的操作,具體解決方案見(jiàn)
廖娟#軟件課程設(shè)計(jì).cpp 的源代碼。軟件課程設(shè)計(jì)
2010年1月開(kāi)發(fā)體會(huì)
剛剛拿到軟件課程設(shè)計(jì)的題目時(shí),我震驚了,二叉樹(shù)?這是什么東西,上學(xué)期學(xué)習(xí)C語(yǔ)言的時(shí)候好像沒(méi)學(xué)到二叉樹(shù)啊。聽(tīng)了老師的介紹才知道做這個(gè)題目的軟件課程設(shè)計(jì)還要先學(xué)習(xí)一下數(shù)據(jù)結(jié)構(gòu)中關(guān)于二叉樹(shù)部分的知識(shí),當(dāng)時(shí)我真的是有些不知所措,本就不怎么好的C語(yǔ)言加上完全不會(huì)的數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)使我開(kāi)始懷疑:三個(gè)星期后我可以完成這份關(guān)于二叉樹(shù)的查找的軟件課程設(shè)計(jì)嗎?
最初的幾天也確實(shí)很沒(méi)有頭緒,只是想著想把老師給的資料都看了,看完了之后走一步算一步吧,可是看完了之后發(fā)現(xiàn)仍然沒(méi)有很大的收獲,連怎么二叉樹(shù)到底有什么用都不知道,對(duì)于這個(gè)題目依然是十分陌生。可是時(shí)間緊迫啊,于是找了位學(xué)習(xí)過(guò)數(shù)據(jù)結(jié)構(gòu)的同學(xué)借了本數(shù)據(jù)結(jié)構(gòu)的書(shū),研究了一番,在加上在網(wǎng)上搜索了一番終于有些頭緒了,知道這份課設(shè)到底要我們做什么了!
接下來(lái)的幾天,隨著了解的加深,自己開(kāi)始慢慢的做課設(shè)了,當(dāng)然從和同學(xué)的交流中,我也學(xué)到了很多。這之后我一步步的完成了對(duì)設(shè)計(jì)示例的注釋,對(duì)遞歸算法的理解,以及先序遍歷、中序遍歷、后序遍歷程序的書(shū)寫(xiě),最終完成了程序的開(kāi)發(fā)。程序開(kāi)發(fā)中我記憶最深刻的就是編寫(xiě)選擇操作的提示界面和初始界面的時(shí)候,為了使界面更加友好,加入了一些人性化的語(yǔ)句,以及為了出現(xiàn)歡迎界面進(jìn)行的許多次試驗(yàn),慢慢的我覺(jué)得這個(gè)過(guò)程十分有趣,看著自己編排的界面出現(xiàn)在面前心中還是有些許成就感的。當(dāng)然除了這些還有很令我頭疼的 光信0804廖娟
U200813197
程序調(diào)試過(guò)程:在程序的調(diào)試階段,發(fā)現(xiàn)程序中有許多問(wèn)題,有的根本不知道從哪入手解決問(wèn)題,甚至不知道為什么會(huì)出現(xiàn)錯(cuò)誤,也因此耗費(fèi)了很多時(shí)間,讓我苦悶了很久。
在這段時(shí)間里,因?yàn)橛熊浖n程設(shè)計(jì),讓我學(xué)到了很多知識(shí),收獲了很多我,自我感覺(jué)自己解決問(wèn)題的能力提高了,并且掌握了軟件開(kāi)發(fā)的一些基本的方法和技巧。還記得寫(xiě)課設(shè)報(bào)告的時(shí)候,花了一天的時(shí)間把報(bào)告里面的所有圖都畫(huà)完了,從剛開(kāi)始的不會(huì)用畫(huà)圖軟件,到后來(lái)慢慢摸索最后熟練運(yùn)用,畫(huà)圖的速度是越來(lái)越快了,讓我后來(lái)甚是欣慰。
經(jīng)過(guò)了這一次的軟件課程設(shè)計(jì),我感受到了C語(yǔ)言的魅力,也深切的體會(huì)到了“學(xué)海無(wú)涯”這四個(gè)字的分量。在以后的日子里,我所需要學(xué)習(xí)的東西還有很多很多,應(yīng)了那句“書(shū)山有路勤為徑,學(xué)海無(wú)涯苦作舟?!?軟件課程設(shè)計(jì)
2010年1月
附錄:源代碼清單
廖娟#注釋.cpp #include
*/ #include
/* 定義二叉樹(shù)結(jié)構(gòu)
*/ struct tree
{
char info;
// 定義char型變量,存放數(shù)據(jù)
struct tree *left,*right;
// 左子樹(shù)指針,右子樹(shù)指針
};/* 定義結(jié)構(gòu)指針變量,作用創(chuàng)建二叉樹(shù)
*/ struct tree *create_btree(struct tree *root,struct tree *r,char info);/* 定義結(jié)構(gòu)指針變量,作用查詢數(shù)據(jù)
*/ struct tree *search_btree(struct tree *root,char key);/* 定義子函數(shù),作用打印二叉樹(shù)
*/ void print_btree(struct tree *r,int l);
/* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 主函數(shù)
*/ void main(){
char s[100],c,key=' ';
struct tree *root=0;
// 定義結(jié)構(gòu)指針根結(jié)點(diǎn),初始化為0
/* 讀入二叉樹(shù)的各個(gè)結(jié)點(diǎn)的值,并將其插入到二叉樹(shù)中
*/
do {
printf(“Enter a letter:”);
gets(s);
// 數(shù)據(jù)輸入過(guò)程
if(!root)
root=create_btree(root,root,*s);
// 如果二叉樹(shù)還未建立,則建立根結(jié)點(diǎn)并保存數(shù)據(jù)
else
create_btree(root,root,*s);// 如果二叉樹(shù)已建立,則建立新的子樹(shù)
}
while(*s);
// 直到s字符串為空,停止輸入
print_btree(root,0);光信0804廖娟
U200813197
/* 查找具有指定值的結(jié)點(diǎn)
*/ key='1';while(key){
printf(“Enter a key to find:”);
scanf(“%s”,&c);
root=search_btree(root,c);
printf(“press to continuen”);} }
/* Btree.C 結(jié)束
*/
/* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 創(chuàng)建二叉樹(shù)
*/ struct tree *create_btree(struct tree *root,struct tree *r,char info)/* struct tree *root:根結(jié)點(diǎn)
struct tree *r:要增加的結(jié)點(diǎn)
char info:要保存的數(shù)據(jù)
*/ {
if(r==0)
// 如果當(dāng)前位置無(wú)結(jié)點(diǎn),則將新結(jié)點(diǎn)插入此處
{
r=new(struct tree);
// same as function: malloc(sizeof())
if(r == 0)
{
printf(“Out of memoryn”);
return 0;
}
r->left= 0;
r->right=0;
r->info=info;
// root為空,則插入后保存至根結(jié)點(diǎn)處
if(root)
// 如果二叉樹(shù)存在,則將新建結(jié)點(diǎn)與二叉樹(shù)連接起來(lái)
{
if(info
root-> left=r;
else
root-> right=r;
// 按左結(jié)點(diǎn)<父結(jié)點(diǎn)<=右結(jié)點(diǎn),保存數(shù)據(jù)
}
else
// 如果根結(jié)點(diǎn)不存在,即二叉樹(shù)不存在,則將新建一個(gè)二叉樹(shù)
{
r->right=0;
r->left=0;軟件課程設(shè)計(jì)
2010年1月
}
return r;}
/* if = = 0 接下頁(yè)
*/
/* 判斷要插入的節(jié)點(diǎn)應(yīng)該在當(dāng)前節(jié)點(diǎn)的左子樹(shù)或右子樹(shù),遞歸插入
*/ if(info < r->info)
create_btree(r,r->left,info);if(info>=r->info)
create_btree(r,r->right,info);}
/* create_btree(root,r,info)*/
/* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 查詢數(shù)據(jù)
*/ struct tree *search_btree(struct tree *root,char key)/* struct tree *root:要查詢的二叉樹(shù)首地址
char key:要查詢的數(shù)據(jù)
*/ {
if(!root)
// 如果二叉樹(shù)指針為空,輸出Empty btree {
printf(“Empty btreen”);
return root;
}
while(root->info!=key)
{
if(key
// 按照“左結(jié)點(diǎn)<父結(jié)點(diǎn)<=右結(jié)點(diǎn)”查找
root=root->left;
else
root=root->right;
if(root==0)
// 如果指針為空,則退出查找
{
printf(“Search Failuren”);
break;
} } /* while(root->info!=key)*/ if(root!=0)
// 如果二叉樹(shù)指針不為空,即查找成功給出信息,返回
printf(“Successful searchn key=%cn”,root->info);return root;} /* *search_btree(root,key)*/
/* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ 光信0804廖娟
U200813197
/* 打印二叉樹(shù)
*/ void print_btree(struct tree *r,int l)/* struct tree *r:二叉樹(shù)首地址
int l:當(dāng)前結(jié)點(diǎn)的高度,根結(jié)點(diǎn)為0
輸出的二叉樹(shù)為正常樹(shù)逆旋轉(zhuǎn)90°后成鏡像的結(jié)果
*/ {
int i;if(r == 0)
return;
//如果傳入指針為0,則返回
print_btree(r->left,l+1);
//打印左結(jié)點(diǎn)
for(i=0;i printf(“ ”); //打印空格,用來(lái)排版控制格式 printf(“%cn”,r->info); //打印根結(jié)點(diǎn) print_btree(r->right,l+1); //打印右結(jié)點(diǎn) } /* *print_btree(root,0) */ 軟件課程設(shè)計(jì) 2010年1月 廖娟#軟件課程設(shè)計(jì).cpp #include */ #include /* 定義二叉樹(shù)結(jié)構(gòu) */ struct tree { char info; // 定義char型變量,存放數(shù)據(jù) struct tree *left,*right; // 左子樹(shù)指針,右子樹(shù)指針 };/* 定義結(jié)構(gòu)指針變量,作用創(chuàng)建二叉樹(shù) */ struct tree *create_btree(struct tree *root,struct tree *r,char info);/* 定義結(jié)構(gòu)指針變量,作用查詢數(shù)據(jù) */ struct tree *search_btree(struct tree *root,char key);/* 定義子函數(shù),作用打印二叉樹(shù) */ void print_btree(struct tree *r,int l);/* 定義子函數(shù),作用先序遍歷 */ void PreorderTraversal(struct tree *root);/* 定義子函數(shù),作用中序遍歷 */ void InorderTraversal(struct tree *root);/* 定義子函數(shù),作用后序遍歷 */ void PostorderTraversal(struct tree *root); /* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 主函數(shù) */ void main(){ char s[100],c; int n;struct tree *root=0; // 定義結(jié)構(gòu)指針根結(jié)點(diǎn),初始化為0 printf(“ ###”);printf(“## ##”);printf(“## 軟件課程設(shè)計(jì): 二叉樹(shù)的查找 ##”);printf(“## ##”);printf(“## 班 級(jí): 光 信0 8 0 4 ##”);光信0804廖娟 U200813197 printf(“## ##”);printf(“## 姓 名: 廖 娟 ##”);printf(“## ##”);printf(“## 學(xué) 號(hào): U 2 0 0 8 1 3 1 9 7 ##”);printf(“## ##”);printf(“ ###”);printf(“n”);printf(“ 程 序 運(yùn) 行 開(kāi) 始 啦!!nn”); /* 讀入二叉樹(shù)的各個(gè)結(jié)點(diǎn)的值,并將其插入到二叉樹(shù)中 */ do { printf(“ 請(qǐng) 輸 入 一 個(gè) 字 符:”); gets(s); // 數(shù)據(jù)輸入過(guò)程 printf(“n”); if(!root) root=create_btree(root,root,*s); // 如果二叉樹(shù)還未建立,則建立根結(jié)點(diǎn)并保存數(shù)據(jù) else create_btree(root,root,*s); // 如果二叉樹(shù)已建立,則建立新的子樹(shù) } while(*s); // 直到s字符串為空,停止輸入 printf(“ 打 印 的 二 叉 樹(shù) 如 下:n”);print_btree(root,0); printf(“ ###”); printf(“## ##”); printf(“## ★★★★★★★★★ 請(qǐng)輸入您想要執(zhí)行的操作!: ★★★★★★★★★ ##”); printf(“## ##”); printf(“## 選擇1—————————————進(jìn)行先序遍歷 ##”); printf(“## ##”);軟件課程設(shè)計(jì) 2010年1月 printf(“## 選擇2—————————————進(jìn)行中序遍歷 ##”); printf(“## ##”); printf(“## 選擇3—————————————進(jìn)行后序遍歷 ##”); printf(“## ##”); printf(“## 選擇4—————————————進(jìn)行查詢結(jié)點(diǎn) ##”); printf(“## ##”); printf(“## 選擇5—————————————進(jìn)行退出操作 ##”); printf(“## ##”); printf(“## ★★★★★★★★★ 溫馨提示:請(qǐng)選擇數(shù)字鍵0~5 ★★★★★★★★★ ##”); printf(“## ##”); printf(“ ###”);while(1){ scanf(“%d”,&n); switch(n) { case 1: printf(“ 先 序 遍 歷 為:n”); PreorderTraversal(root); printf(“nn”); break; case 2: printf(“ 中 序 遍 歷 為:n”); InorderTraversal(root); printf(“nn”); break; case 3: printf(“ 后 序 遍 歷 為:n”); PostorderTraversal(root); printf(“nn”); break; case 4: 光信0804廖娟 U200813197 printf(“ 請(qǐng) 輸 入 您 要 查 詢 的 結(jié) 點(diǎn):n”); scanf(“%s”,&c); printf(“ 您 要 查 詢 的 結(jié) 點(diǎn) 為:n”); root=search_btree(root,c); printf(“n”); break; case 5: printf(“ 光 信 0 8 0 4 ———— 廖 娟nn”); printf(“ 0 1 0 年 1 月nn”); return; default: printf(“ 您 的 輸 入 有 誤,請(qǐng) 重 新 輸 入!!n”); break; } } } /* Btree.C 結(jié)束 */ /* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ struct tree *create_btree(struct tree *root,struct tree *r,char info)/* struct tree *root:根結(jié)點(diǎn) struct tree *r:要增加的結(jié)點(diǎn) char info:要保存的數(shù)據(jù) */ { if(r==0) // 如果當(dāng)前位置無(wú)結(jié)點(diǎn),則將新結(jié)點(diǎn)插入此處 { r=new(struct tree); // same as function: malloc(sizeof()) if(r == 0) { printf(“ Out of memoryn”); return 0; } r->left= 0; r->right=0; r->info=info; // root為空,則插入后保存至根結(jié)點(diǎn)處 if(root) // 如果二叉樹(shù)存在,則將新建結(jié)點(diǎn)與二叉樹(shù)連接起來(lái) 軟件課程設(shè)計(jì) 2010年1月 { if(info root-> left=r; else root-> right=r; // 按左結(jié)點(diǎn)<父結(jié)點(diǎn)<=右結(jié)點(diǎn),保存數(shù)據(jù) } else // 如果根結(jié)點(diǎn)不存在,即二叉樹(shù)不存在,則將新建一個(gè)二叉樹(shù) { r->right=0; r->left=0; } return r;} /* if = = 0 接下頁(yè) */ /* 判斷要插入的節(jié)點(diǎn)應(yīng)該在當(dāng)前節(jié)點(diǎn)的左子樹(shù)或右子樹(shù),遞歸插入 */ if(info < r->info) create_btree(r,r->left,info);if(info>=r->info) create_btree(r,r->right,info);} /* *create_btree(root,r,info)*/ /* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 查詢數(shù)據(jù) */ struct tree *search_btree(struct tree *root,char key)/* struct tree *root:要查詢的二叉樹(shù)首地址 char key:要查詢的數(shù)據(jù) */ { tree *t;t=root;if(!t) // 如果二叉樹(shù)指針為空,輸出Empty btree { printf(“ Empty btree!!n”); return root; } while(t->info!=key) { if(key // 按照“左結(jié)點(diǎn)<父結(jié)點(diǎn)<=右結(jié)點(diǎn)”查找 t=t->left; else t=t->right; if(t==0) // 如果指針為空,則退出查找 光信0804廖娟 U200813197 { printf(“ Search Failure!!n”); break; } } /* while(root->info!=key)*/ if(t!=0) // 如果二叉樹(shù)指針不為空,即查找成功給出信息,返回 printf(“ Successful search!!n key=%cn”,t->info);return root;} /* *search_btree(root,key)*/ /* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 打印二叉樹(shù) */ void print_btree(struct tree *r,int l)/* struct tree *r:二叉樹(shù)首地址 int l:當(dāng)前結(jié)點(diǎn)的高度,根結(jié)點(diǎn)為0 輸出的二叉樹(shù)為正常樹(shù)逆旋轉(zhuǎn)90°后成鏡像的結(jié)果 */ { int i;if(r == 0) return; //如果傳入指針為0,則返回 print_btree(r->left,l+1); //打印左結(jié)點(diǎn) for(i=0;i printf(“ ”); //打印空格,用來(lái)排版控制格式 printf(“%cn”,r->info); //打印根結(jié)點(diǎn) print_btree(r->right,l+1); //打印右結(jié)點(diǎn) } /* *print_btree(root,0) */ /* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 先序遍歷 */ void PreorderTraversal(struct tree *root){ if(root==0) return;printf(“%c”,root->info);PreorderTraversal(root->left);PreorderTraversal(root->right);} 軟件課程設(shè)計(jì) 2010年1月 /* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 中序遍歷 */ void InorderTraversal(struct tree *root){ if(!root) return;InorderTraversal(root->left);printf(“%c”,root->info);InorderTraversal(root->right);} /* O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ O(∩_∩)O~ */ /* 后序遍歷 */ void PostorderTraversal(struct tree *root){ if(!root) return;PostorderTraversal(root->left);PostorderTraversal(root->right);printf(“%c”,root->info);} 參考文獻(xiàn) 《數(shù)據(jù)結(jié)構(gòu)》(c語(yǔ)言版)嚴(yán)蔚敏 吳偉民 編著 清華大學(xué)出版社 《C語(yǔ)言程序設(shè)計(jì)》 譚浩強(qiáng) 編著 清華大學(xué)出版社 《C程序上機(jī)指導(dǎo)》 譚浩強(qiáng) 編著 清華大學(xué)出版社 《標(biāo)準(zhǔn)c語(yǔ)言程序設(shè)計(jì)及應(yīng)用》 周純杰 編著 華中科技大學(xué)出版社 軟件項(xiàng)目管理的理論與實(shí)踐 摘要:本文在探討CMM/CMMI、敏捷編程等相關(guān)理論的基礎(chǔ)上,結(jié)合軟件開(kāi)發(fā)實(shí)踐,提出了平衡敏捷與紀(jì)律的軟件管理思想,并探討了融合敏捷與CMM/CMMI的最佳實(shí)踐。 關(guān)鍵詞:CMM/CMMI,敏捷 當(dāng)CMM遭遇敏捷 本世紀(jì)初,在國(guó)務(wù)院18號(hào)文件《鼓勵(lì)軟件產(chǎn)業(yè)和集成電路產(chǎn)業(yè)發(fā)展的若干政策》的推動(dòng),以及鼎新、東軟等先驅(qū)軟件企業(yè)的帶動(dòng)下,國(guó)內(nèi)掀起了一陣CMM風(fēng)暴(CMM于2000年升級(jí)為CMMI,文中在不特別針對(duì)某個(gè)具體版本時(shí),使用CMM泛指CMM/CMMI),軟件企業(yè)的CMM/CMMI評(píng)估形成了一股席卷全國(guó)的潮流。據(jù)CSDN統(tǒng)計(jì),截止到2010年9月,我國(guó)通過(guò)CMM/CMMI評(píng)估的企業(yè)已達(dá)到1300家,全球排名第二。一時(shí)之間,CMM似乎成為了衡量軟件企業(yè)開(kāi)發(fā)能力的唯一標(biāo)準(zhǔn),成了發(fā)展我國(guó)信息技術(shù)行業(yè)的銀彈。然而,自2005年開(kāi)始,一些有識(shí)之士就已經(jīng)認(rèn)識(shí)到CMM的局限性,紛紛撰文提出質(zhì)疑。目前,隨著越來(lái)越多軟件企業(yè)CMM神話的破滅,CMM已經(jīng)完全走下神壇。現(xiàn)在打開(kāi)百度,搜索CMM的相關(guān)內(nèi)容,除去概念、介紹性的文章外,對(duì)其持否定態(tài)度占了絕大部分,繼續(xù)力挺CMM的文章幾乎絕跡。由此可見(jiàn),中國(guó)的軟件界已經(jīng)從CMM的狂熱階段轉(zhuǎn)入理性階段。 在CMM由盛轉(zhuǎn)衰的同時(shí),以強(qiáng)調(diào)人本、效率為核心的敏捷思想開(kāi)始悄然興起。從Kent Beck的極限編程(eXtreme Programing,簡(jiǎn)稱XP)和敏捷聯(lián)盟的敏捷宣言中,中國(guó)程序員開(kāi)始聽(tīng)到CMM外的聲音。而隨著Martin Fowler、Robert Martin等敏捷大師登陸中國(guó),數(shù)屆敏捷大會(huì)在北京召開(kāi),整個(gè)中國(guó)軟件界掀起了一股以務(wù)實(shí)、高效、簡(jiǎn)約為特征的敏捷風(fēng)。目前,軟件行業(yè)的媒體、雜志上,充斥著介紹XP、Scrum等敏捷方法的專題文章,秉承敏捷思想進(jìn)行管理的軟件企業(yè)隨處可見(jiàn),敏捷成了過(guò)程改進(jìn)的最熱門(mén)話題。 面對(duì)CMM的盛極而衰和敏捷的方興未艾,我們不禁要問(wèn):CMM到底怎么了?敏捷真的適合我們嗎?我們?cè)摵稳ズ螐模?CMM怎么了 我第一次接觸CMM是2000年。在此之前,我一直試圖尋找一套軟件開(kāi)發(fā)標(biāo)準(zhǔn),曾經(jīng)學(xué)習(xí)過(guò)GB 85-88和IEEE-830、IEEE-12207等軟件工程標(biāo)準(zhǔn),但一知半解,遠(yuǎn)沒(méi)有形成一個(gè)系統(tǒng)化過(guò)程的概念。CMM的豐富、廣博確實(shí)讓我眼前一亮,好象打開(kāi)了一面通向世界軟件技術(shù)的窗戶,看到了從未想象過(guò)的世界。但是,CMM那些繁復(fù)的規(guī)定和要求,又讓我望而卻步,“可遠(yuǎn)觀而不可褻玩焉”。2002年,在信產(chǎn)部政策的推動(dòng)下,各地方政府紛紛出臺(tái)了獎(jiǎng)勵(lì)政策,稍具規(guī)模的軟件公司,都在躍躍欲試地準(zhǔn)備CMM評(píng)估,CMM才真正走到我們面前,雖然當(dāng)時(shí)還不完全了解CMM到底能帶給我們什么。 其后幾年,CMM/CMMI成了我工作的一部分,我對(duì)它有了更深刻的了解??梢哉f(shuō),CMM是中國(guó)軟件行業(yè)規(guī)范化的啟蒙者。CMMI-DEV 1.2的22個(gè)PA、48個(gè)特定目標(biāo)、165個(gè)特殊實(shí)踐,覆蓋到了軟件開(kāi)發(fā)和管理的方方面面,讓我們真正了解到什么是軟件管理。每個(gè)職業(yè)軟件人,無(wú)論是開(kāi)發(fā)者還是管理者,都有必要了解、掌握這些內(nèi)容。作為一個(gè)指導(dǎo)軟件企業(yè)過(guò)程改進(jìn)的框架,CMMI提供了階段型和連續(xù)型兩種方法論,并通過(guò)5個(gè)通用目標(biāo)、17個(gè)通用實(shí)踐,清晰地描繪了一條軟件企業(yè)走向成熟的路線。比如CMMI-DEV 1.2 Ⅱ級(jí)的目標(biāo),就是“管起來(lái)”,無(wú)論你用什么方法,只要把計(jì)劃、度量、需求、配置、質(zhì)量保證等內(nèi)容管起來(lái),就認(rèn)為是達(dá)到了Ⅱ級(jí)。當(dāng)Ⅱ級(jí)積累到一定程度,認(rèn)為各項(xiàng)目間有必要共享各自的經(jīng)驗(yàn)的時(shí)候,就可以向Ⅲ邁進(jìn)了。遺憾的是,我們?cè)谝M(jìn)CMM的過(guò)程中,犯了急功近利的毛病,囫圇吞棗,沒(méi)有真正按照框架的精神踏踏實(shí)實(shí)地進(jìn)行過(guò)程改進(jìn),導(dǎo)致了CMM的水土不服。究其原因,我覺(jué)得問(wèn)題應(yīng)該出在以下幾個(gè)方面: 1.CMM的移植問(wèn)題。CMM起源于美國(guó)國(guó)防部和國(guó)家宇航局,所針對(duì)的都是大型項(xiàng)目。這些項(xiàng)目失敗的成本巨大,對(duì)軟件質(zhì)量要求非常之高,因此,對(duì)過(guò)程的精細(xì)程度要求非常之高。在制定模型時(shí),為了做到方法的完備性,所制定的過(guò)程框架又涵蓋了各種情形,使過(guò)程模型更加復(fù)雜化。在移植到中國(guó)后,由于評(píng)估時(shí)間等的壓力,我們并沒(méi)有充分地消化CMM的精髓,沒(méi)有考慮我們企業(yè)所能承受的成本,沒(méi)有根據(jù)項(xiàng)目的實(shí)際情況進(jìn)行有效裁剪,而是僵化地全套照搬,建立了過(guò)于復(fù)雜的管理流程,形成了大量面面俱到卻無(wú)人問(wèn)津的過(guò)程制品,反倒失去了對(duì)項(xiàng)目核心的掌控,導(dǎo)致生產(chǎn)效率降低,產(chǎn)品質(zhì)量下降。而過(guò)程改進(jìn)人員又普遍脫離了開(kāi)發(fā)實(shí)踐,CMM成了教條,使開(kāi)發(fā)人員產(chǎn)生了反感情緒。 2.CMM缺少工程方法。CMM是一個(gè)能力標(biāo)準(zhǔn),只講要做什么,卻沒(méi)講怎么做。例如CMMI-DEV 1.2 Ⅱ級(jí)的7個(gè)PA,全部是項(xiàng)目管理的內(nèi)容,基本未提及工程方法。CMMI-DEV 1.2 Ⅲ的11個(gè)PA,雖然涉及到RD、TS、PI等技術(shù)領(lǐng)域的內(nèi)容,但只提了宏觀要求,并未涉及細(xì)節(jié)。這種設(shè)計(jì)方式,是因?yàn)镃MM的創(chuàng)建者假定軟件企業(yè)已經(jīng)具備了適合本企業(yè)的、完整有效的軟件工程方法論。我國(guó)企業(yè)在引進(jìn)CMM前,基本上還沒(méi)有形成自己的軟件過(guò)程和文檔體系,而是寄希望于CMM來(lái)改善這種情況。在CMM實(shí)施中,又普遍存在重管理輕技術(shù)的觀點(diǎn),忽視了企業(yè)資產(chǎn)的建立,通常是照辦咨詢公司提供的模板,沒(méi)有進(jìn)行有效的本地化,沒(méi)有認(rèn)真探索適合自身的工程方法,從而導(dǎo)致管理先進(jìn)、技術(shù)落伍的不良狀態(tài),也從根本上違背了CMM“過(guò)程改進(jìn)”的基本思想。 3.CMM不適合小型項(xiàng)目。CMM起點(diǎn)很高,對(duì)各個(gè)環(huán)節(jié)要求極嚴(yán),是真正的重量級(jí)方法。對(duì)周期短、回報(bào)小、資源不足的小型項(xiàng)目來(lái)說(shuō),使用CMM的成本太高,可以說(shuō)是得不償失。這一點(diǎn),在CMM剛剛進(jìn)入中國(guó)時(shí),SEI的專家們?cè)磸?fù)聲明,CMM的創(chuàng)始人Watts Humphrey老先生也一再?gòu)?qiáng)調(diào)。在CMM之后,Humphrey先生又建立了用于小規(guī)模團(tuán)隊(duì)的TSP(Team Software Process)模型和用于個(gè)人的PSP(Personal Software Process)模型,作為CMM的補(bǔ)充。在為波音公司的IT部門(mén)進(jìn)行CMM咨詢時(shí),Humphrey先生根據(jù)各部門(mén)的實(shí)際情況,分別制定了實(shí)施CMM Ⅲ、CMM Ⅱ、TSP、PSP的不同方案。由此可見(jiàn),CMM并不是放諸四海而皆準(zhǔn)的銀彈,無(wú)論是公司還是項(xiàng)目,選擇CMM,都應(yīng)該根據(jù)自己的實(shí)際情況進(jìn)行理性的選擇,而不應(yīng)該生搬硬套,以命令的形式強(qiáng)制推行。反過(guò)來(lái),如果選擇了CMM,就要提供足夠的資源,否則就會(huì)事與愿違,反倒降低效率,影響產(chǎn)品進(jìn)度和質(zhì)量。 4.CMM的知識(shí)更新問(wèn)題。CMM初稿是在1986年提出的,87年正式發(fā)布1.0版。它的基本內(nèi)容,都是基于瀑布模型設(shè)計(jì)的。按照《人件》和《最后期限》的作者Tom DeMarco的說(shuō)法,“CMM 已經(jīng)有超過(guò) 20 年的歷史,它的成功經(jīng)驗(yàn)都是在 1985 年前獲得的。CMM 試圖將一個(gè)固定的模型強(qiáng)加于一個(gè)日新月異的行業(yè)之上,它鼓勵(lì)你效仿 IBM 在 1970 年代所采用的軟件開(kāi)發(fā)方式。僵化,不敢面對(duì)變化,這是如今的軟件業(yè)最忌諱的。”2006年8月發(fā)布的CMMI-DEV 1.2版本,開(kāi)始尋求對(duì)這一局限進(jìn)行突破,但是進(jìn)展甚微。例如,目前迭代式開(kāi)發(fā)已經(jīng)被公認(rèn)是先進(jìn)的開(kāi)發(fā)組織模式,可以有效應(yīng)對(duì)變化。而CMM在某些方面卻限制了迭代的應(yīng)用。比如里程碑式的需求評(píng)審、設(shè)計(jì)評(píng)審,就是典型的瀑布模型的影響,與迭代方法中隨著開(kāi)發(fā)的深入逐步獲取需求的思路完全矛盾,造成了兩者的沖突,客觀上限制了基于迭代的新式工程模型的應(yīng)用。 5.實(shí)施過(guò)程中理論和實(shí)際的脫離。國(guó)內(nèi)的CMM實(shí)施,最頭疼的就是找不到合適的SEPG和QA人選。按照CMM的思想,SEPG和QA應(yīng)該來(lái)自具有豐富開(kāi)發(fā)經(jīng)驗(yàn)的技術(shù)人員,能在開(kāi)發(fā)過(guò)程中得到軟件人員的尊重,并給予全方位的指導(dǎo),從而得到客觀的洞察力。而我們的軟件企業(yè)通常比較年輕,人才積累少,SEPG和QA的軟件經(jīng)驗(yàn)普遍不足,兼之過(guò)于追求理論上的完美,不注重跟蹤過(guò)程執(zhí)行情況,不注重收集反饋信息,導(dǎo)致我們的流程、制度脫離開(kāi)發(fā)實(shí)際,引起開(kāi)發(fā)人員反感。正如軟件界泰斗Boehm博士所說(shuō)的那樣,“過(guò)程改進(jìn)黑暗面的誘惑力是巨大的,實(shí)施者們很容易受其誘惑而陷入只追求表面文章的黑暗面之中”。這樣的過(guò)程改進(jìn)只注重滿足標(biāo)準(zhǔn),片面追求過(guò)程與規(guī)范的符合度,脫離了軟件開(kāi)發(fā)實(shí)踐,忽略了實(shí)踐對(duì)理論的驗(yàn)證、反饋,違背了過(guò)程改進(jìn)的初衷,偏離了提高效率、提高軟件質(zhì)量的根本目標(biāo)。敏捷的特征 以CMM為代表的傳統(tǒng)意義上的軟件方法學(xué)描述,通常“能夠”處理任何大小的項(xiàng)目,而實(shí)際上真正的困難就來(lái)自于如何對(duì)這些方法加以裁剪以適合較小的項(xiàng)目。針對(duì)這種理論與實(shí)際的脫節(jié)現(xiàn)象,敏捷方法應(yīng)運(yùn)而生。相對(duì)于CMM這樣的重量級(jí)方法,敏捷方法常被認(rèn)為是“輕量級(jí)”方法。敏捷的倡導(dǎo)者認(rèn)為,軟件產(chǎn)品開(kāi)發(fā)無(wú)法一開(kāi)始就能定義產(chǎn)品最終的規(guī)程,開(kāi)發(fā)過(guò)程中需要研發(fā)、創(chuàng)意、嘗試錯(cuò)誤,所以沒(méi)有一種固定的流程可以保證專案成功。開(kāi)發(fā)團(tuán)隊(duì)?wèi)?yīng)有明確的最高目標(biāo),熟悉開(kāi)發(fā)流程中所需具備的最佳典范與技術(shù),具有高度自主權(quán),緊密地溝通合作,以高度彈性解決各種挑戰(zhàn),確保每天、每個(gè)階段都朝向目標(biāo)有明確的推進(jìn)。 相對(duì)于傳統(tǒng)方法,敏捷方法更重視“人”在軟件研發(fā)中的作用,重視效率,重視對(duì)變化的積極響應(yīng),倡導(dǎo)迭代式開(kāi)發(fā),反對(duì)機(jī)械地盲從既有過(guò)程,反對(duì)面面俱到、堆積如山卻無(wú)人問(wèn)津的文檔。自1996年敏捷先驅(qū)Kent Beck提出極限編程思想后,敏捷方法得到了廣泛響應(yīng),敏捷愛(ài)好者于2001年成立了敏捷聯(lián)盟,并發(fā)表了敏捷宣言: ? 注重個(gè)人及互動(dòng) 勝于 過(guò)程和工具 ? 注重可用的軟件 勝于 詳盡的文檔 ? 注重客戶協(xié)作 勝于 合同談判 ? 注重響應(yīng)變化 勝于 恪守計(jì)劃 2002年后,敏捷方法得到了迅猛發(fā)展。其中影響至深、波及至廣的當(dāng)屬極限編程(XP)和Scrum方法。 極限編程是敏捷理論的先驅(qū),“極限”的含義是將在開(kāi)發(fā)中總結(jié)的最佳實(shí)踐發(fā)揮到極至。例如,如果你認(rèn)為迭代是好的,那么就將迭代的周期壓縮至最小,甚至幾天、幾小時(shí)一次迭代。嚴(yán)格來(lái)說(shuō),極限編程并不是一套完整的方法論,而是一組核心理念和一套最佳實(shí)踐的組合。XP倡導(dǎo)溝通、反饋、簡(jiǎn)單、勇氣四個(gè)核心價(jià)值觀,主張項(xiàng)目的設(shè)計(jì)、結(jié)構(gòu)要保持簡(jiǎn)單,要注重溝通和用戶反饋,要有勇氣接受變化、重構(gòu)代碼。XP提出了項(xiàng)目計(jì)劃(The planning game)、小版本(Small releases)、隱喻(Metaphor)、簡(jiǎn)單的設(shè)計(jì)(Simple design)、重構(gòu)(Refactoring)、測(cè)試驅(qū)動(dòng)(Test-driven)、結(jié)對(duì)編程(Pair programming)、代碼共享(Collective ownership)、持續(xù)集成(Continuous integration)、不加班(40-hour week)、現(xiàn)場(chǎng)客戶(On-site customer)、編碼標(biāo)準(zhǔn)(Coding standards)等十二個(gè)核心實(shí)踐,其中重構(gòu)、測(cè)試驅(qū)動(dòng)、小版本(迭代)、持續(xù)集成等實(shí)踐已經(jīng)成了敏捷思想的核心,被現(xiàn)代軟件工程理論廣泛接受。XP作為敏捷方法的先驅(qū),最大貢獻(xiàn)是為敏捷方法提供了大量基礎(chǔ)實(shí)踐。它的基本思想被各種敏捷方法廣泛接受、繼承,為敏捷的盛行奠定了基礎(chǔ)。 Scrum方法的名字取源于英式橄欖球爭(zhēng)球隊(duì),其用意就是要把體育比賽中那種團(tuán)結(jié)、拼搏的精神施加于軟件團(tuán)隊(duì)。和XP相比,Scrum提供了更具體的工程管理機(jī)制,從而使Scrum的可操作性更強(qiáng)。這也是近年來(lái)Scrum方法盛行的原因。Scrum方法的核心,是將開(kāi)發(fā)過(guò)程分解為一系列小的迭代,每次迭代稱為一個(gè)Sprint(沖刺)。每個(gè)Sprint通過(guò)計(jì)劃會(huì)議明確任務(wù),通過(guò)每日例會(huì)掌控進(jìn)度、問(wèn)題,通過(guò)評(píng)審會(huì)議總結(jié)成果。如此反復(fù),經(jīng)過(guò)一系列可控的“沖刺”,最終達(dá)成項(xiàng)目目標(biāo)。其基本流程描述如下: 1.列舉可以預(yù)知的所有任務(wù),包括功能性和非功能性任務(wù),形成所謂Backlog。2.將整個(gè)產(chǎn)品的Backlog分解成一系列Sprint Backlog,這個(gè)Sprint Backlog是按照目前的人力物力條件可以完成的。3.召開(kāi)Sprint計(jì)劃會(huì)議,劃分、確定這個(gè)Sprint內(nèi)需要完成的任務(wù),標(biāo)注任務(wù)的優(yōu)先級(jí)并分配給每個(gè)成員。Sprint的任務(wù)是以小時(shí)計(jì)算的,并不是按人天計(jì)算。 4.進(jìn)入Sprint開(kāi)發(fā)周期,在這個(gè)周期內(nèi),每天需要召開(kāi)15分鐘的每日Scrum例會(huì)。5.整個(gè)Sprint周期結(jié)束,召開(kāi)Sprint review meeting,將成果演示給Product Owner。該會(huì)議為外部會(huì)議,邀請(qǐng)干系人參加,一般不超過(guò)4小時(shí)。 6.團(tuán)隊(duì)成員最后召開(kāi)Sprint retrospective meeting,總結(jié)問(wèn)題和經(jīng)驗(yàn)。該會(huì)議為內(nèi)部會(huì)議,時(shí)間不超過(guò)3小時(shí)。 7.這樣周而復(fù)始,按照同樣的步驟進(jìn)行下一次Sprint。 無(wú)論是XP還是Scrum,其基本思想都是互通的。它們所倡導(dǎo)的最佳實(shí)踐,看似一個(gè)個(gè)獨(dú)立活動(dòng),實(shí)際上具有很高的耦合度,不能孤立地執(zhí)行。例如,XP的共享代碼權(quán),如果沒(méi)有編碼標(biāo)準(zhǔn)、結(jié)對(duì)編程作為基礎(chǔ),是很難實(shí)現(xiàn)的;小版本沒(méi)有重構(gòu)作為保障,會(huì)導(dǎo)致結(jié)構(gòu)的混亂;Scrum的每日例會(huì),要以“站立會(huì)議”的方式進(jìn)行,以保證效率;Scrum的Sprint要以持續(xù)集成、重構(gòu)等實(shí)踐作為保證,否則無(wú)法維護(hù)產(chǎn)品的完整性和可靠性,等等。 敏捷以一種充滿活力的方式,挑戰(zhàn)了傳統(tǒng)軟件工程思想的沉悶,激起了全球軟件人員的強(qiáng)烈反響。然而,任何事情都有其不利的一面,敏捷也是如此。敏捷無(wú)法管理大型項(xiàng)目,即使對(duì)比較適合敏捷的中小項(xiàng)目來(lái)說(shuō),敏捷也有自身的弱點(diǎn),例如: 1.敏捷過(guò)于依靠個(gè)人素質(zhì)和Team leader的領(lǐng)導(dǎo)能力,因此在團(tuán)隊(duì)成員較新,缺乏足夠的經(jīng)驗(yàn)、技巧和敬業(yè)精神時(shí),敏捷會(huì)失效; 2.敏捷經(jīng)常會(huì)被誤解成不寫(xiě)文檔。事實(shí)上,敏捷反對(duì)的只是面面具到、求全責(zé)備的文檔和過(guò)程,而不排斥必要的文檔。例如XP的12個(gè)核心實(shí)踐,就提到項(xiàng)目計(jì)劃、隱喻和簡(jiǎn)單的設(shè)計(jì)三個(gè)涉及文檔的活動(dòng)。敏捷只是提倡用一種更直接、更輕量、更易于理解的方式編寫(xiě)文檔,而不是一概否定文檔。 由此可見(jiàn),以CMM為代表的傳統(tǒng)方法和敏捷思想實(shí)際是事務(wù)對(duì)立統(tǒng)一的兩個(gè)方面。傳統(tǒng)方法強(qiáng)調(diào)過(guò)程、強(qiáng)調(diào)紀(jì)律,而敏捷方法強(qiáng)調(diào)個(gè)體、強(qiáng)調(diào)創(chuàng)造。如果將兩種思想有機(jī)結(jié)合起來(lái),取長(zhǎng)補(bǔ)短,達(dá)到平衡,就能找出更合適的過(guò)程改進(jìn)之路。平衡敏捷與規(guī)范 在敏捷與傳統(tǒng)為誰(shuí)是誰(shuí)非的問(wèn)題爭(zhēng)論的不可開(kāi)交的時(shí)候,一些有識(shí)之士已經(jīng)在考慮兩者的融合。其中比較有代表性的一位,是以創(chuàng)造了COCOMO模型、螺旋模型和經(jīng)典名著《軟件工程經(jīng)濟(jì)學(xué)》而聞名的Boehm博士。Boehm博士在2003年出版了《Balancing Agility an Discipline》一書(shū),對(duì)平衡敏捷和規(guī)范的問(wèn)題進(jìn)行了詳細(xì)的論述。該書(shū)的中文版《平衡敏捷與規(guī)范》也已經(jīng)于2005年由清華大學(xué)出版社出版??梢?jiàn),平衡敏捷與規(guī)范,已經(jīng)是被國(guó)內(nèi)外學(xué)者所認(rèn)同的發(fā)展之路。敏捷與規(guī)范之爭(zhēng),大致可以歸結(jié)為以下兩個(gè)方面: 1.人與過(guò)程孰重孰輕之爭(zhēng),或者軟件到底是“工程”還是 “藝術(shù)”之爭(zhēng); 2.質(zhì)量尺度的把握,或者說(shuō),需要為質(zhì)量付出多少成本。 人與過(guò)程之爭(zhēng),焦點(diǎn)是軟件開(kāi)發(fā)過(guò)程創(chuàng)造性的地位問(wèn)題。CMM把軟件開(kāi)發(fā)過(guò)程看作一個(gè)工程過(guò)程,希望利用在制造業(yè)等傳統(tǒng)行業(yè)中獲得的經(jīng)驗(yàn)來(lái)管理軟件開(kāi)發(fā),對(duì)開(kāi)發(fā)中的“個(gè)人英雄主義”行為持明確的否定態(tài)度,倍加推崇正確的過(guò)程、嚴(yán)格的工序和絕對(duì)的紀(jì)律。而敏捷方法的核心就是強(qiáng)調(diào)發(fā)揮個(gè)人或團(tuán)隊(duì)的創(chuàng)造性,主張按照項(xiàng)目特點(diǎn)選擇過(guò)程。在敏捷專家看來(lái),沒(méi)有什么規(guī)范是固定不變的,所有過(guò)程都由人而定,都是為項(xiàng)目成功服務(wù)的。敏捷和規(guī)范各有所長(zhǎng),以CMM為代表的規(guī)范過(guò)程更適合需求明確的大型項(xiàng)目,而敏捷更適合具有挑戰(zhàn)性的研究項(xiàng)目。 質(zhì)量尺度的把握。CMM強(qiáng)調(diào)質(zhì)量至上,不會(huì)因?yàn)樾薁奚|(zhì)量。敏捷強(qiáng)調(diào)效率,一些敏捷方法提出了“滿意質(zhì)量”的概念。滿意質(zhì)量基于“任何事情都帶來(lái)成本,而我們所想要的總是超過(guò)我們的支付能力;質(zhì)量在本質(zhì)上是有條件的和主觀的;為了在軟件方面達(dá)到完美,我們不得不解決許多困難問(wèn)題、達(dá)成許多折衷和解決相互沖突的價(jià)值,完美不會(huì)很容易或機(jī)械性地實(shí)現(xiàn)”的基本前提,提出了滿意質(zhì)量的定義:(1)可帶來(lái)足夠的利益;(2)不存在致命性問(wèn)題;(3)所帶來(lái)的利益超過(guò)問(wèn)題所造成的損失;(4)在當(dāng)前條件下綜合考慮所有因素后,進(jìn)一步的改進(jìn)所帶來(lái)的損害大于其帶來(lái)的幫助。滿意質(zhì)量否定了質(zhì)量至上的觀念,說(shuō)明了敏捷思想更加務(wù)實(shí)的價(jià)值觀。應(yīng)該說(shuō),CMM的質(zhì)量目標(biāo)更適合作為一種文化或信念,而滿意質(zhì)量是對(duì)質(zhì)量目標(biāo)更理性的思考,更具有說(shuō)服力和實(shí)用性。 敏捷強(qiáng)調(diào)個(gè)體、強(qiáng)調(diào)效率,但同時(shí)對(duì)個(gè)體素質(zhì)要求較高,局限性較大。而CMM強(qiáng)調(diào)過(guò)程,強(qiáng)調(diào)質(zhì)量,更適合于簡(jiǎn)單、重復(fù)的生產(chǎn)活動(dòng),很難應(yīng)付復(fù)雜多變的情況。事實(shí)上,敏捷與規(guī)范正是軟件開(kāi)發(fā)過(guò)程中兩個(gè)不可或缺的方面。過(guò)分強(qiáng)調(diào)自由,開(kāi)發(fā)過(guò)程就會(huì)失控,回到軟件危機(jī)前的“混沌”狀態(tài);而過(guò)分強(qiáng)調(diào)規(guī)范,又會(huì)導(dǎo)致僵化,扼殺人的主動(dòng)性和創(chuàng)造力。因此,軟件管理的目標(biāo),就是平衡敏捷和規(guī)范的矛盾,使開(kāi)發(fā)活動(dòng)高效、有序地進(jìn)行。對(duì)已經(jīng)通過(guò)了CMM/CMMI評(píng)估,但仍希望持續(xù)改進(jìn)的軟件企業(yè),我覺(jué)得最直接的平衡方法,是用敏捷的觀點(diǎn)重新審視既有規(guī)范,用效率觀點(diǎn)重新評(píng)價(jià)各種管理活動(dòng),逐步剔除其僵化、低效的部分,最終達(dá)到平衡。具體方法可概括如下。 1.對(duì)項(xiàng)目分類進(jìn)一步精細(xì)化,提供更豐富的生命周期模型,并提供與之相適應(yīng)的模板和規(guī)范要求,使之能夠盡量適應(yīng)不同類型項(xiàng)目的情況。通過(guò)CMM/CMMI評(píng)估的企業(yè)所采用的流程規(guī)范,大多是繼承自咨詢公司提供的模板。雖然在改進(jìn)過(guò)程中有適當(dāng)裁減,但并未真正接受實(shí)踐的檢驗(yàn),而且普遍不能支持新的生命周期模型。要想讓規(guī)范更好地支持開(kāi)發(fā)過(guò)程,幫助企業(yè)提高開(kāi)發(fā)效率、產(chǎn)品質(zhì)量,就應(yīng)該不斷吸納新知識(shí)、新思想,不斷建立新模型,使企業(yè)資產(chǎn)庫(kù)不斷得到擴(kuò)充。另一方面,企業(yè)資產(chǎn)庫(kù)對(duì)開(kāi)發(fā)部門(mén)應(yīng)該是開(kāi)放的。開(kāi)發(fā)人員是推動(dòng)企業(yè)知識(shí)更新最積極的因素,管理人員應(yīng)該積極支持、幫助、配合項(xiàng)目組使用創(chuàng)新方法、過(guò)程,認(rèn)真跟蹤、觀察新方法的執(zhí)行效果,及時(shí)總結(jié)經(jīng)驗(yàn)教訓(xùn),將新方法及時(shí)合并到企業(yè)資產(chǎn)庫(kù)。 2.提供更靈活的裁減條件,減少不必要的中間環(huán)節(jié),給予項(xiàng)目經(jīng)理更多的控制權(quán)限。任何過(guò)程都有其局限性,而每個(gè)項(xiàng)目都有其特殊性,不可能通過(guò)機(jī)械地復(fù)制既有過(guò)程就達(dá)到復(fù)制成功的目的。這一點(diǎn),SEI的專家也是認(rèn)同的,CMM的Ⅱ級(jí)命名為“可重復(fù)級(jí)”,升級(jí)到CMMI時(shí)更名為“管理級(jí)”,就隱含了這個(gè)道理。軟件不同于簡(jiǎn)單的生產(chǎn)加工活動(dòng),是一個(gè)充滿挑戰(zhàn)和創(chuàng)造性的工作,軟件管理也不可能完全照搬企業(yè)管理的經(jīng)驗(yàn),而必須強(qiáng)調(diào)“人”,特別是項(xiàng)目經(jīng)理在整個(gè)過(guò)程中的主導(dǎo)作用。給予項(xiàng)目經(jīng)理更多的控制權(quán)限,尤其是過(guò)程裁減的權(quán)限,更有利于發(fā)揮項(xiàng)目經(jīng)理的聰明才智,引導(dǎo)項(xiàng)目走向成功。這是敏捷思想的精髓所在。對(duì)開(kāi)發(fā)過(guò)程中的管理活動(dòng),要深入分析其對(duì)具體項(xiàng)目的作用,才能作出是否需要的合理判斷。以專家評(píng)審為例。理論上,專家評(píng)審可以集中專家的智慧,對(duì)開(kāi)發(fā)活動(dòng)肯定是有益的。但某些企業(yè)由于環(huán)境、業(yè)務(wù)復(fù)雜度、技術(shù)復(fù)雜度、人際關(guān)系等等原因,專家可能不愿意或沒(méi)能力提供有效意見(jiàn),這樣評(píng)審就不能達(dá)到預(yù)期目的。如果評(píng)審成了走過(guò)場(chǎng),就要引發(fā)深度思考,考慮評(píng)審所帶來(lái)的收益是否大于付出的成本,并決定是否裁減評(píng)審活動(dòng)了。裁減的最終決策權(quán)應(yīng)該交給項(xiàng)目經(jīng)理,而不是SEPG人員。因?yàn)轫?xiàng)目經(jīng)理要對(duì)項(xiàng)目總體負(fù)責(zé),只有他最了解、最關(guān)注項(xiàng)目的成本、進(jìn)度、質(zhì)量,其它人員的意見(jiàn)都具有局限性、片面性。 3.管理體制要從實(shí)踐中來(lái),到實(shí)踐中去。所有針對(duì)軟件開(kāi)發(fā)的管理活動(dòng),都是為了讓開(kāi)發(fā)工作更有效、更可靠、更可控,都是為開(kāi)發(fā)服務(wù)的。敏捷的最大魅力,就是所有最佳實(shí)踐都是來(lái)自于開(kāi)發(fā)活動(dòng)的,所以才會(huì)得到開(kāi)發(fā)人員的廣泛擁戴。因此,管理制度的制定,尤其是過(guò)程、文檔模板的制定,要堅(jiān)持實(shí)踐是檢驗(yàn)真理唯一標(biāo)準(zhǔn)的原則,堅(jiān)持從開(kāi)發(fā)實(shí)踐中總結(jié)經(jīng)驗(yàn),積累財(cái)富。要杜絕閉門(mén)造車式的過(guò)程改進(jìn),無(wú)論多么完美的理論,都要經(jīng)過(guò)實(shí)踐檢驗(yàn)后,才能驗(yàn)證其正確性。軟件管理人員必須具備軟件開(kāi)發(fā)經(jīng)驗(yàn),并不斷深入開(kāi)發(fā)實(shí)踐,體會(huì)規(guī)范的實(shí)際運(yùn)用效果。管理規(guī)范要經(jīng)過(guò)實(shí)踐檢驗(yàn)后才能形成制度,并且要考慮是否能為開(kāi)發(fā)人員所接受,所增加的管理成本是否物有所值等因素。如果脫離了實(shí)際,制度就會(huì)僵化,變成阻礙開(kāi)發(fā)工作的束縛,達(dá)到適得其反的目的。 4.發(fā)現(xiàn)問(wèn)題,量體裁衣,逐步實(shí)現(xiàn)過(guò)程改進(jìn)。羅馬不是一天建成的,任何進(jìn)步都要有一個(gè)普及、接受、適應(yīng)的過(guò)程。CMMI 的組織過(guò)程焦點(diǎn)(OPF)明確地列舉了組織過(guò)程改進(jìn)的方法。在CMM實(shí)施階段,由于時(shí)間的壓力,企業(yè)可能沒(méi)有真正按照CMM的精神來(lái)實(shí)施過(guò)程改進(jìn),急于求全、求大,或多或少地存在制度與實(shí)際兩層皮的情況。要改變這種狀態(tài),應(yīng)該堅(jiān)持持續(xù)改進(jìn)的精神,改進(jìn)要按照OPF的要求,評(píng)價(jià)組織過(guò)程,發(fā)現(xiàn)最薄弱環(huán)節(jié),找出最緊迫的過(guò)程改進(jìn)需要,制定改進(jìn)計(jì)劃,實(shí)施過(guò)程改進(jìn)。按照這種方式,即使每次改進(jìn)僅完成一個(gè)PA,只要真正落到實(shí)處,就會(huì)取得實(shí)際的進(jìn)步。如此反復(fù),企業(yè)就會(huì)得到真正的發(fā)展。如果違背了這個(gè)規(guī)律,一味求大求全,浮于表面,過(guò)程改進(jìn)可能永遠(yuǎn)是一句空話。5平衡管理與技術(shù) 在平衡敏捷與規(guī)范的討論中,還有一個(gè)不容忽視的問(wèn)題,就是平衡管理與技術(shù)的關(guān)系。軟件是一個(gè)技術(shù)密集型行業(yè),是一種純腦力勞動(dòng),技術(shù)對(duì)于項(xiàng)目成功的重要性,是不庸質(zhì)疑的。在CMM登陸之前,我們普遍存在重技術(shù)、輕管理的現(xiàn)象。CMM作為一個(gè)管理框架,重點(diǎn)在于強(qiáng)調(diào)管理,正是對(duì)片面強(qiáng)調(diào)技術(shù)的糾正。然而,隨著CMM思想的不斷深入,又難免產(chǎn)生矯枉過(guò)正的情況,反倒讓軟件企業(yè)忘記了立身之本,忽略了技術(shù)的地位,造成管理至上的錯(cuò)誤。管理與技術(shù)孰輕孰重?如何擺正管理與技術(shù)的關(guān)系?要想平衡管理與規(guī)范,這些問(wèn)題都是不可避免的。 1.軟件開(kāi)發(fā)活動(dòng)中技術(shù)的地位問(wèn)題。軟件不同于傳統(tǒng)企業(yè),軟件產(chǎn)品的形成過(guò)程,主要依靠人的思維活動(dòng),是看不見(jiàn)、摸不著的。管理的目的,是為了引導(dǎo)人的思維活動(dòng)按正確的方式發(fā)展,但是決不能替代人的思維。有人說(shuō),產(chǎn)生文檔的根本原因,來(lái)自于項(xiàng)目經(jīng)理的恐慌,因?yàn)轫?xiàng)目經(jīng)理無(wú)法感知、控制軟件項(xiàng)目的進(jìn)度和質(zhì)量,只能依賴文檔來(lái)進(jìn)行監(jiān)控。如果忽視了技術(shù)、技能的培養(yǎng),忽視了軟件人員的素質(zhì)建設(shè),思維就失去了基礎(chǔ),僅僅依靠管理、紀(jì)律,是不可能獲得成功的。尤其在客戶要求日益復(fù)雜、技術(shù)日新月異的今天,技術(shù)的重要性越發(fā)突出。一個(gè)良好的設(shè)計(jì)思路、技術(shù)決策,往往是覺(jué)得項(xiàng)目成功的關(guān)鍵。因此,應(yīng)該正確認(rèn)識(shí)技術(shù)在軟件活動(dòng)的地位,尊重知識(shí),尊重技術(shù),讓管理為技術(shù)服務(wù)。 2.客觀分析企業(yè)的狀態(tài)。管理和技術(shù)是保證項(xiàng)目成功的兩個(gè)決定因素,不能偏廢。作為企業(yè)領(lǐng)導(dǎo),要實(shí)現(xiàn)過(guò)程改進(jìn),就要客觀分析企業(yè)的狀態(tài),分析清楚企業(yè)現(xiàn)在的弱項(xiàng)是管理還是技術(shù),然后再制定相關(guān)政策,而不能想當(dāng)然地片面強(qiáng)調(diào)某一方面,加劇不平衡狀態(tài)。我個(gè)人認(rèn)為,在沒(méi)有實(shí)施任何認(rèn)證的企業(yè),忽視管理的可能性較大;在通過(guò)了ISO9000、CMM的企業(yè),則往往夸大了管理,忽視了技術(shù)。 3.客觀分析管理和技術(shù)的分別。面對(duì)企業(yè)在開(kāi)發(fā)過(guò)程中暴露出來(lái)的問(wèn)題,要進(jìn)行客觀、深入的分析,判斷是管理問(wèn)題還是技術(shù)問(wèn)題,再采取相應(yīng)措施。比如現(xiàn)在普遍存在的需求失控的問(wèn)題,從表面上看,是需求開(kāi)發(fā)(ReqD)和管理(ReqM)的問(wèn)題。但是,如果深入到問(wèn)題本質(zhì),可能會(huì)發(fā)現(xiàn),需求變更是不可避免的。那么,就要從架構(gòu)設(shè)計(jì)和開(kāi)發(fā)過(guò)程方面找問(wèn)題。例如可以采用組件式開(kāi)發(fā),讓軟件易于適應(yīng)變化;可以使用原型法,讓用戶盡早看到產(chǎn)品;或者使用迭代式開(kāi)發(fā),及時(shí)規(guī)避風(fēng)險(xiǎn),讓產(chǎn)品逐步接近用戶目標(biāo)。如果死鉆牛角尖,一味在需求調(diào)研、文檔、評(píng)審上下功夫,就會(huì)事倍功半,降低效率。 4.注重技術(shù)人才的培養(yǎng)?!吧w成非常之事,必待非常之人”。兩千年前的漢武帝,就已經(jīng)認(rèn)識(shí)到人才的重要性。正是因?yàn)榫哂胁痪幸桓裼萌瞬诺姆欠矚馄牵瑵h武帝才能挖掘出衛(wèi)青、霍去病這樣的軍事天才,建立不世之功。在軟件行業(yè),也不乏蓋茨、裘伯軍、王江民這樣以一己之力獲得巨大成功的先例。因此,軟件研發(fā),尤其是開(kāi)拓性軟件的研發(fā),必須要有大批具有專業(yè)知識(shí)、超凡能力的“非常之人”。軟件企業(yè)要具備容納百川的胸懷,重視技術(shù)人才的挖掘、培養(yǎng),提供鉆研技術(shù)的環(huán)境,打造尊重技術(shù)的企業(yè)環(huán)境,造就技術(shù)過(guò)硬的拔尖人才,才能提高自身素質(zhì),建立企業(yè)的核心競(jìng)爭(zhēng)力,在市場(chǎng)上保持競(jìng)爭(zhēng)優(yōu)勢(shì)。結(jié)束語(yǔ) 前文在剖析CMM的利弊的基礎(chǔ)上,用敏捷觀點(diǎn)重新審視了過(guò)程改進(jìn)的方法,并闡述了軟件企業(yè)中管理和技術(shù)的關(guān)系。最后,我們?cè)倩仡櫼幌旅艚菪?,?quán)作本文的結(jié)束語(yǔ)吧。 ? 注重個(gè)人能力,注重創(chuàng)新,注重互動(dòng),反對(duì)僵化的過(guò)程和低效的工具 ? 注重編寫(xiě)好用的軟件,反對(duì)面面具到卻無(wú)人問(wèn)津的文檔 ? 注重客戶協(xié)作,避免生硬的商務(wù)談判 ? 注重適應(yīng)變化,響應(yīng)變化,反對(duì)墨守成規(guī),恪守計(jì)劃 1自動(dòng)化測(cè)試 傳統(tǒng)的測(cè)試已經(jīng)無(wú)法滿足測(cè)試的需要,自動(dòng)化測(cè)試應(yīng)運(yùn)而生,自動(dòng)化測(cè)試是指在預(yù)設(shè)條件下運(yùn)行,包括正常條件和異常條件,自動(dòng)化主要研究的是自動(dòng)化框架測(cè)試、自動(dòng)化測(cè)試腳本技術(shù)、自動(dòng)化用例生成。通過(guò)資料了解,C-ATFM模型。該模型基于C語(yǔ)言,面向?qū)ο蠹森h(huán)境,采用源碼嵌入有效的分析軟件的代碼、詞法、語(yǔ)法、策略、指令。并且隨著軟件工程及軟件測(cè)試的發(fā)展,自動(dòng)化的機(jī)器測(cè)試發(fā)展更有前景。 2下面簡(jiǎn)介軟件測(cè)試的過(guò)程 2.1模塊測(cè)試 模塊測(cè)試主要針對(duì)軟件設(shè)計(jì)中的程序模塊,通過(guò)測(cè)試技術(shù)測(cè)試程序塊是否正確,模塊測(cè)試的主要目的是測(cè)試程序內(nèi)部的錯(cuò)誤,根據(jù)程序設(shè)計(jì)的結(jié)構(gòu)檢查代碼和程序是否合理,是否符合設(shè)計(jì)思路和理念,是否能夠正常運(yùn)行。 2.2組裝測(cè)試 在模塊的基礎(chǔ)上,需要將所有模塊的功能全部測(cè)試完成后組裝成為系統(tǒng),組裝測(cè)試的目的在于,連接所有模塊之后,模塊之間的接口、觸發(fā)器是否能正常運(yùn)行,并且計(jì)算顯示的數(shù)據(jù)是否正確,模塊之間的功能是否互相沖突,是否達(dá)到預(yù)期的目的和結(jié)果顯示,是否構(gòu)成正確的、預(yù)期的數(shù)據(jù)結(jié)構(gòu)。不同模塊之間的誤差有多少,有多少可以解決,有多少不能解決。 2.3確認(rèn)測(cè)試 確認(rèn)測(cè)試的目的是驗(yàn)證軟件的功能和特性是否達(dá)到預(yù)期的愿望,是否能按照預(yù)期的組織結(jié)構(gòu)、系統(tǒng)結(jié)構(gòu)、用例分析和時(shí)序分析運(yùn)作,并且進(jìn)行驗(yàn)收測(cè)試和安裝測(cè)試。 2.4系統(tǒng)測(cè)試 系統(tǒng)測(cè)試是確認(rèn)軟件是否與硬件互相支持,是否能滿足軟件使用者對(duì)軟件的需求和操作簡(jiǎn)便的愿望,比如說(shuō)查詢模塊運(yùn)行完后界面中查詢條件應(yīng)該為查詢之間輸入的查詢條件。系統(tǒng)測(cè)試保證了系統(tǒng)的正常運(yùn)行,另外很重要的就是權(quán)限測(cè)試,系統(tǒng)在研發(fā)之初定義的權(quán)限信息和權(quán)限功能是否實(shí)現(xiàn),是否發(fā)現(xiàn)軟件成品與軟件定義不符合或者矛盾。 3軟件測(cè)試技術(shù)的地位 一個(gè)成功的測(cè)試用例在于發(fā)現(xiàn)了至今尚未發(fā)現(xiàn)的缺陷。其實(shí),軟件編程的過(guò)程也會(huì)出現(xiàn)一些不可避免的錯(cuò)誤,例如:對(duì)于用戶需求的錯(cuò)誤分析和編程出現(xiàn)的一些語(yǔ)法錯(cuò)誤,如果軟件與發(fā)票費(fèi)用相關(guān)更是與測(cè)試密不可分。軟件不斷地接近成熟和完成以及投入使用階段,軟件測(cè)試工程師必須更加謹(jǐn)慎的檢測(cè)每一部分程序,一段程序的完成,測(cè)試工作量占有總工作量40%以上,這就給我們說(shuō)明:測(cè)試是軟件開(kāi)發(fā)成功的重要組成部分。第四篇:軟件項(xiàng)目管理的理論與實(shí)踐
第五篇:軟件測(cè)試技術(shù)與管理方法探討論文