版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
軟件開發(fā)流程管理制度(討論稿)為加強(qiáng)對定制軟件開發(fā)工作管理,縮短開發(fā)周期,提高軟件開發(fā)質(zhì)量,降低開發(fā)成本,提高定開發(fā)效率和效益,特制定軟件開發(fā)流程管理制度。第一章、總則為保證日常工作正常有序的進(jìn)行,讓開發(fā)中各個環(huán)境更緊湊,更可控,需要盡可能實現(xiàn)項目管理的正規(guī)化,工作過程的流程化,以便提高軟件質(zhì)量,按期交付。1、軟件開發(fā)總體遵循項目管理和軟件工程的基本原則。2、項目管理涉及項目立項、項目計劃和監(jiān)控、配置管理。3、軟件工程涉及需求分析、系統(tǒng)設(shè)計、軟件實現(xiàn)、系統(tǒng)測試、用戶測試、試運行、系統(tǒng)驗收、系統(tǒng)上線和數(shù)據(jù)遷移、產(chǎn)品維護(hù)。第二章、階段成果根據(jù)軟件工程的過程,制定以下工作流程,并規(guī)定了各個重要環(huán)節(jié)需要提交的交付物。各階段需提交的文檔:1、立項:項目申請表,軟件需求報告或設(shè)計方案。2、需求分析:項目研發(fā)主計劃、需求規(guī)格說明書3、總體設(shè)計:概要設(shè)計說明書或功能模塊描述4、詳細(xì)設(shè)計:詳細(xì)設(shè)計說明書,包括軟件接口說明、單元測試計劃。5、軟件實現(xiàn):軟件功能說明、源代碼說明或者注釋6、產(chǎn)品測試:測試報告7、產(chǎn)品發(fā)布:產(chǎn)品說明書、使用手冊8、產(chǎn)品維護(hù):問題反饋記錄9、項目總結(jié):提交客戶方的項目總結(jié)和公司項目匯報的PPT。軟件過程成果表:階段形成文檔職責(zé)及文檔成果描述負(fù)責(zé)人涉及范圍備注需求階段項目立項報告(Word)明確甲乙雙方責(zé)任及義務(wù),需雙方簽字確認(rèn)項目經(jīng)理驗收報告大部分業(yè)務(wù)建模和需求,少部分分析設(shè)計業(yè)務(wù)需求說明書(Word)需求定義,闡述業(yè)務(wù)范圍及內(nèi)容,開發(fā)組負(fù)責(zé)制定最優(yōu)技術(shù)設(shè)計方案項目經(jīng)理/分析員驗收報告項目開發(fā)計劃(Project)用戶、領(lǐng)導(dǎo)、項目組都了解項目進(jìn)度項目經(jīng)理驗收報告設(shè)計階段業(yè)務(wù)流程總體設(shè)計書、詳細(xì)設(shè)計說明書(Word/Visio)項目組成員分配任務(wù),并召開討論會議,討論項目的技術(shù)架構(gòu)和可能存在的技術(shù)難點,梳理業(yè)務(wù)流程,統(tǒng)一開發(fā)規(guī)則和風(fēng)格等項目經(jīng)理/分析員驗收報告大部分分析設(shè)計,部分實施編程及測試,開始考慮部署數(shù)據(jù)庫關(guān)系設(shè)計圖、流程圖(PowerDesigner)便于項目開發(fā)分析員驗收報告任務(wù)分配文檔(Word)明確每個組員的開發(fā)任務(wù)及職責(zé)項目經(jīng)理過程報告問題說明報告(Word)讓用戶、領(lǐng)導(dǎo)及組員及時了解和發(fā)現(xiàn)問題項目經(jīng)理過程報告業(yè)務(wù)變更文檔(Word)記錄開發(fā)過程中用戶提出的業(yè)務(wù)需求變更情況分析員過程報告測試階段項目測試方案及報告(Word)記錄項目測試的方法,驗證系統(tǒng)功能與性能的記錄測試員驗收報告反復(fù)測試直至系統(tǒng)穩(wěn)定用戶使用手冊(Word)方便用戶使用軟件而提供的使用說明書測試員驗收報告上線及運行系統(tǒng)切換報告系統(tǒng)部署后的操作記錄項目經(jīng)理過程報告部署及維護(hù)用戶培訓(xùn)報告用戶培訓(xùn)文檔項目經(jīng)理過程報告項目驗收報告(Word)記錄甲乙雙方簽訂項目驗收報告項目經(jīng)理驗收報告項目總結(jié)性報告項目組通過此項目總結(jié)經(jīng)驗及不足項目經(jīng)理總結(jié)報告第三章、崗位設(shè)置根據(jù)公司目前的開發(fā)過程主要分為分析、開發(fā)、測試三個階段。分析階段完成用戶需求文檔的編寫,系統(tǒng)總體設(shè)計的編寫;開發(fā)階段完成設(shè)計文檔的編寫,代碼的編寫、代碼的維護(hù)。測試階段完成系統(tǒng)的測試,測試文檔及其他材料。通過逐漸的調(diào)整崗位,明確工作職責(zé),逐步實現(xiàn)項目經(jīng)理,軟件設(shè)計師,程序員,測試工程師的崗位設(shè)置。崗位工作內(nèi)容責(zé)任項目經(jīng)理1、選定項目組成員,成立項目組,安排任務(wù)分工2、與客戶進(jìn)行溝通和協(xié)調(diào)(業(yè)務(wù)需求或非業(yè)務(wù)需求方面),以及需求調(diào)研工作。3、制定開發(fā)主計劃,包括需求,設(shè)計,編碼,測試這幾個階段的計劃。4、估計項目開發(fā)費用5、制定小組開發(fā)進(jìn)度表,對組內(nèi)人員工作進(jìn)度監(jiān)控。6、和客戶進(jìn)行溝通,進(jìn)行需求調(diào)研,匯總需求分析文檔,并編寫系統(tǒng)總體設(shè)計方案7、對文檔的質(zhì)量進(jìn)行檢查、把關(guān)8、對組內(nèi)成員的工作進(jìn)行指導(dǎo)1、對客戶的溝通協(xié)調(diào)工作負(fù)責(zé);2、對軟件的開發(fā)效率、質(zhì)量、費用負(fù)責(zé)3、對用戶的需求分析的質(zhì)量負(fù)責(zé);4、對系統(tǒng)總體設(shè)計、詳細(xì)設(shè)計文檔質(zhì)量負(fù)責(zé)軟件設(shè)計師1、負(fù)責(zé)系統(tǒng)的模塊設(shè)計,詳細(xì)設(shè)計文檔2、繪制界面原型demo等,設(shè)計功能使用的具體描述、行為者、前置條件、后置條件、UI描述、業(yè)務(wù)流程/子流程/分支流程,界面說明等,完成大部分的前端設(shè)計,小部分的后端設(shè)計。3、負(fù)責(zé)技術(shù)難度大的模塊的代碼或者公用模塊代碼的編寫、維護(hù)4、對自己負(fù)責(zé)模塊的詳細(xì)設(shè)計、代碼編寫。5、對小組內(nèi)人員進(jìn)行技術(shù)指導(dǎo)1、對組內(nèi)人員的開發(fā)效率負(fù)責(zé);2、對產(chǎn)品整體風(fēng)格負(fù)責(zé)3、對項目整體設(shè)計流程負(fù)責(zé);4、對自己模塊的開發(fā)效率和質(zhì)量負(fù)責(zé)。程序員1、與項目經(jīng)理溝通和確認(rèn)某個模塊的需求和實現(xiàn)方法2、負(fù)責(zé)某個模塊的代碼編寫、維護(hù)3、對其他模塊的代碼的維護(hù)4、負(fù)責(zé)與測試人員的交互,處理測試人員的問題1、對自己模塊的開發(fā)效率和質(zhì)量負(fù)責(zé)。測試工程師1、根據(jù)用戶需求分析和系統(tǒng)總體設(shè)計,編寫測試文檔和測試用例。2、對系統(tǒng)的功能、性能、異常進(jìn)行測試。3、編寫測試文檔和操作指導(dǎo)手冊。1、對測試的質(zhì)量負(fù)責(zé)2、對測試文檔和操作手冊的質(zhì)量負(fù)責(zé)。第四章、項目立項1、分析人員進(jìn)行應(yīng)用調(diào)查與分析,確認(rèn)軟件的應(yīng)用需求。2、成立項目評審會,開發(fā)總監(jiān)、部門經(jīng)理和指定人員必須參加。對項目進(jìn)行可行性研究,編寫項目建議書,評估項目的難度和工作量,形成可行性研究報告。3、根據(jù)項目配置的優(yōu)劣成立項目開發(fā)組,制定軟件開發(fā)計劃,確定項目經(jīng)理,由部門和項目經(jīng)理共同來確定具體項目配置,知識技能要求,團(tuán)隊成員及團(tuán)隊的角色。第五章、項目計劃與監(jiān)控1、以項目為單位,項目經(jīng)理負(fù)責(zé)整個項目的計劃、組織和控制。2、在整個項目過程中,項目經(jīng)理定期檢查項目進(jìn)度和完成情況,調(diào)整人員分工和安排。3、項目計劃需要變更時,需要明確變更內(nèi)容并及時匯報。項目經(jīng)理需要說明客戶變更原因并將變更說明提交公司領(lǐng)導(dǎo)審核,以便根據(jù)變更內(nèi)容及時調(diào)整計劃。。第六章、需求分析1、對用戶提出的需求進(jìn)行分析匯總,梳理用戶的業(yè)務(wù)流程和詳細(xì)的功能定義。2、做出簡單的界面原型,與客戶進(jìn)行有效的溝通,編寫需求詳細(xì)說明書。3、根據(jù)現(xiàn)有條件進(jìn)行估計,制定項目進(jìn)度,制定詳細(xì)的軟件開發(fā)計劃。第七章、總體設(shè)計1、在該階段確定總體結(jié)構(gòu)和軟件開發(fā)架構(gòu),文件命名規(guī)范,編碼規(guī)范??砂窜浖枨髣澐殖勺酉到y(tǒng),也可直接定義目標(biāo)系統(tǒng)的功能模塊及各個功能模塊的關(guān)系。3、確定軟件模塊結(jié)構(gòu),給出每個功能模塊的功能描述、數(shù)據(jù)接口描述,并完成系統(tǒng)概要設(shè)計說明書。4、完成數(shù)據(jù)庫的設(shè)計,并編寫數(shù)據(jù)庫設(shè)計說明書。5、完成的文檔需提交公司進(jìn)行歸檔管理。第八章、詳細(xì)設(shè)計1、調(diào)整前一步設(shè)計的不足,確認(rèn)各模塊之間的詳細(xì)接口信息。2、設(shè)計功能使用的具體描述、行為者、前置條件、后置條件、UI描述、業(yè)務(wù)流程/子流程/分支流程,界面說明等。3、確定模塊內(nèi)的數(shù)據(jù)流或控制流,對每個程序模塊必須確定所有輸入、輸出和處理功能。4、匯總并提交所有相關(guān)文檔,審核確認(rèn)質(zhì)量和進(jìn)度。第九章、軟件實現(xiàn)1、項目組根據(jù)概要設(shè)計說明書、詳細(xì)設(shè)計說明書制定系統(tǒng)實現(xiàn)計劃2、有條件的情況下保證開發(fā)、測試和生產(chǎn)環(huán)境獨立。選擇軟件工具,明確項目成員的職責(zé)分工,按照編碼規(guī)范和詳細(xì)設(shè)計實現(xiàn)軟件功能。3、代碼應(yīng)滿足結(jié)構(gòu)良好,清晰易讀,且與設(shè)計一致,符合編碼規(guī)范。4、開發(fā)人員需要軟件實現(xiàn)過程中編寫軟件功能說明,源代碼說明。軟件功能說明文檔應(yīng)說明項目名稱、編號、軟件名稱和版本號,軟件功能、主要功能實現(xiàn)過程。源代碼說明應(yīng)說明項目編號、軟件名稱、功能,全局變量、數(shù)據(jù)庫字典、函數(shù)功能、接口。該文檔包含在源代碼文件中,以注釋形式存在。5、項目組進(jìn)行單元測試和集成測試。開發(fā)人員處理測試人員反饋的測試問題,并以書面形式反饋主要問題及解決辦法,直至系統(tǒng)運行穩(wěn)定。6、匯總并提交所有相關(guān)文檔,提交公司備案。第十章、軟件測試1、根據(jù)單據(jù)測試和集成測試兩個過程,制定測試計劃。按階段設(shè)計測試實例,并將測試結(jié)果記錄,未通過的的反饋給開發(fā)人員調(diào)整。2、完成測試文檔、操作手冊、安裝維護(hù)手冊的編寫。第十一章、用戶培訓(xùn)1、準(zhǔn)備用戶培訓(xùn)計劃、培訓(xùn)手冊2、確定培訓(xùn)時間、培訓(xùn)地點,向用戶進(jìn)行系統(tǒng)使用培訓(xùn)、操作指導(dǎo)及提供軟件操作手冊。3、保留培訓(xùn)簽到表,用戶意見等存檔。第十二章、系統(tǒng)上線1、制定上線計劃,確定上線工作時間表,部署的環(huán)境。2、上線操作步驟以及問題處理步驟;3、根據(jù)軟件特點、客戶需求進(jìn)行軟件部署,并記錄軟件部署和運行結(jié)果;4、項目組根據(jù)系統(tǒng)運行請款對系統(tǒng)進(jìn)行優(yōu)化,記錄系統(tǒng)的運行情況、系統(tǒng)問題和處理后的版本。第十三章、系統(tǒng)驗收1、驗收工作準(zhǔn)備,按要求整理項目成果物,打印裝訂成冊,并提交客戶方。2、系統(tǒng)主要使用部門及信息技術(shù)部門聯(lián)合成立項目驗收小組,從需求功能及技術(shù)需求層面對系統(tǒng)進(jìn)行綜合評估和項目成果物的審核,根據(jù)驗收情況形成系統(tǒng)驗收報告3、應(yīng)用部門及信息技術(shù)部門負(fù)責(zé)人根據(jù)系統(tǒng)試運行情況簽署驗收意見。第十四章、產(chǎn)品維護(hù)1、調(diào)出項目主要開發(fā)人員,按照合同要求安排維護(hù)人員對系統(tǒng)進(jìn)行技術(shù)支持。2、系統(tǒng)需求變更或調(diào)整,記錄變更原因和軟件及源代碼的版本控制,按照軟件變更要求對系統(tǒng)進(jìn)行維護(hù)。第章十五、源碼和文檔1、源代碼/文檔管理采用版本控制軟件SVN。2、按項目的階段性完成源代碼、文檔的上傳。項目負(fù)責(zé)人每天對代碼進(jìn)行檢查,開發(fā)總監(jiān)或部門經(jīng)理定期進(jìn)行抽查。3、文檔分為項目文檔和個人文檔,文檔上傳前進(jìn)行歸類和匯總。第十六章、質(zhì)量檢查1、項目負(fù)責(zé)人每天要檢查成員的工作完成情況,特別是新員工的工作進(jìn)展;2、工作抽查制度:不定期的進(jìn)行抽檢,并將檢查對象、檢查時間、檢查內(nèi)容、檢查結(jié)果反饋給被抽檢人。3、內(nèi)部審核制度:針對業(yè)務(wù)需求、概要設(shè)計(功能界面、數(shù)據(jù)庫)或疑難問題組織評審會,提出意見或解決方案。第十七章、文檔規(guī)范1、需按照軟件實施的階段落實成果物,參照《軟件過程提交成果表》。2、如果客戶有特殊要求,請按照客戶要求的規(guī)范完成。并將最終的問題提交公司歸檔備份。第十八章、軟件變更為規(guī)范軟件變更與維護(hù)管理,特制定本制度。本制度適用于應(yīng)用系統(tǒng)開發(fā)完畢并正式上線,移交給客戶方之后的運行支持及系統(tǒng)變更工作。1、系統(tǒng)變更工作可分為功能完善維護(hù)、系統(tǒng)缺陷修改、統(tǒng)計報表生成。2、需求部門提出系統(tǒng)變更需求,開發(fā)部技術(shù)支持人員根據(jù)重要性和緊迫性做判斷,確定其優(yōu)先級和影響程度,并進(jìn)行相應(yīng)處理,同時將變更需求整理成系統(tǒng)變更申請表。3、系統(tǒng)變更實現(xiàn)過程按照軟件開發(fā)過程規(guī)定進(jìn)行,遵循軟件開發(fā)過程統(tǒng)一的編碼標(biāo)準(zhǔn)和版本控制,并經(jīng)過測試通過才能完成部署和上線。4、在系統(tǒng)變更完成后,開發(fā)人員需將系統(tǒng)變更表的執(zhí)行結(jié)果找業(yè)務(wù)部門負(fù)責(zé)人簽字后,提交至公司進(jìn)行歸檔管理。軟件開發(fā)流程規(guī)范V1.0德聯(lián)軟件有限責(zé)任公司編制人:侯秀美審核人:2015年8月19日目錄目錄 一、概述本文制定煙臺開發(fā)區(qū)德聯(lián)軟件有限責(zé)任公司計算機(jī)軟件開發(fā)規(guī)范文檔。本規(guī)范的目的是使公司軟件開發(fā)項目階段清晰、要求明確、任務(wù)具體、編寫的代碼規(guī)范,使之規(guī)范化、系統(tǒng)化和工程化,向公司內(nèi)從事軟件開發(fā)的工程師和管理人員提出一系列規(guī)范和要求,從而有利于開發(fā)過程的控制和管理,提高所開發(fā)軟件系統(tǒng)的質(zhì)量,縮短開發(fā)時間,減少開發(fā)和維護(hù)費用,以保證項目高質(zhì)量、順利進(jìn)行。本規(guī)范包含:開發(fā)流程規(guī)范和開發(fā)代碼規(guī)范等,開發(fā)流程規(guī)范需要技術(shù)開發(fā)人員編寫相關(guān)內(nèi)容,希望每個技術(shù)人員形成習(xí)慣,如有新的內(nèi)容更新會及時通知大家,如有好的規(guī)范要求也可通知編制人員及時更新。本規(guī)范為煙臺開發(fā)區(qū)德聯(lián)軟件有限責(zé)任公司內(nèi)部材料,嚴(yán)禁其他商業(yè)應(yīng)用。二、開發(fā)流程規(guī)范 接受開發(fā)任務(wù),詳細(xì)閱讀軟件技術(shù)規(guī)范或技術(shù)文檔,如對技術(shù)文檔有疑義或者不清楚的地方及時與項目總工或用戶溝通,根據(jù)文檔和溝通內(nèi)容編寫項目開發(fā)計劃,必須包括但不限于系統(tǒng)軟硬件開發(fā)環(huán)境、系統(tǒng)架構(gòu)、系統(tǒng)功能模塊設(shè)計、系統(tǒng)功能開發(fā)流程圖、開發(fā)修改記錄。2.1系統(tǒng)軟硬件開發(fā)環(huán)境開發(fā)環(huán)境的搭建,最好形成文檔,便于以后同樣工作的使用。開發(fā)人員要明確系統(tǒng)開發(fā)擬采用的數(shù)據(jù)庫、操作系統(tǒng)、開發(fā)語言、開發(fā)工具、服務(wù)器等(具體到版本)。明確整個系統(tǒng)開發(fā)工作流程,至少應(yīng)該包括以下流程。2.2系統(tǒng)架構(gòu)(系統(tǒng)組成)確定系統(tǒng)整體體系架構(gòu),各層次之間的數(shù)據(jù)流的連接,確定軟件服務(wù)器的硬件配置及用戶硬件資源配置,確定與用戶軟件平臺的統(tǒng)一協(xié)調(diào)。開發(fā)人員在繪制架構(gòu)圖時給出基本框架,能反映出基本意義即可,可以直接用文字代替例子中的圖片。圖1系統(tǒng)邏輯架構(gòu)圖舉例圖2物理架構(gòu)圖舉例2.3系統(tǒng)功能模塊設(shè)計給出系統(tǒng)的主要功能模塊,每個模塊所包含的功能。圖3圖書管理系統(tǒng)模塊規(guī)劃圖舉例2.4系統(tǒng)功能開發(fā)流程圖給出系統(tǒng)主要功能的業(yè)務(wù)流程圖。圖4系統(tǒng)功能業(yè)務(wù)流程圖舉例2.5開發(fā)修改記錄1.開發(fā)代碼做好備份(可以在完成一個重大功能之后,或者按時間周期性進(jìn)行備份),以免由于不可抗力導(dǎo)致代碼不可修復(fù)。2.在每次重大修改之后要做好記錄(改動的具體細(xì)節(jié)),修改前的版本要及時備份,可以方面隨時還原系統(tǒng)。修改日期修改內(nèi)容是否備份備注
三、開發(fā)代碼規(guī)范 在研究項目團(tuán)隊協(xié)作開發(fā)的情況下(這里的團(tuán)隊協(xié)作也適合于應(yīng)用項目的開發(fā)),編程時應(yīng)該強(qiáng)調(diào)的一個重要方面是程序的易讀性,在保證軟件速度等性能指標(biāo)能滿足用戶需求的情況下,能讓其他程序員容易讀懂你所編寫的程序。若研究項目小組的所有開發(fā)人員都遵循統(tǒng)一的、鮮明的一套編程風(fēng)格,可以讓協(xié)作者、后繼者和自己一目了然,在很短的時間內(nèi)看清楚程序結(jié)構(gòu),理解設(shè)計的思路,大大提高代碼的可讀性、可重用性、程序健壯性、可移植性、可維護(hù)性。 制定本編程規(guī)范的目的是為了提高軟件開發(fā)效率及所開發(fā)軟件的可維護(hù)性,提高軟件的質(zhì)量。本規(guī)范由程序風(fēng)格、命名規(guī)范、注釋規(guī)范、程序健壯性、可移植性、錯誤處理以及軟件的模塊化規(guī)范等部分組成。 此規(guī)范以C/C++程序設(shè)計討論。3.1文件結(jié)構(gòu) 每個C++/C程序通常分為兩個文件。一個文件用于保存程序的聲明(declaration),稱為頭文件。另一個文件用于保存程序的實現(xiàn)(implementation),稱為定義(definition)文件。 C++/C程序的頭文件以“.h”為后綴,C程序的定義文件以“.c”為后綴,C++程序的定義文件通常以“.cpp”為后綴(也有一些系統(tǒng)以“.cc”或“.cxx”為后綴)。3.1.1文件信息聲明文件信息聲明位于頭文件和定義文件的開頭(參見示例3-1),主要內(nèi)容有:(1)
版權(quán)信息;(2)
文件名稱,項目代碼,摘要,參考文獻(xiàn);(3)
當(dāng)前版本號,作者/修改者,完成日期;(4)
版本歷史信息;(5)
主要函數(shù)描述。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Copyright(c)2015,DeLianSoftCompanyYanTai//Allrightsreserved.////Filename:filename.h//ProjectCode:Theprojectcodeaboutthisfile//Abstract:Describethecontentofthisfilesummarily//Reference:////Version:1.1//Author:thenameofauthor(mender)//Accomplisheddate:September2,2004////Replacedversion:1.0//OriginalAuthor:thenameoforiginalauthor(mender)//Accomplisheddate:September10,2003////Mainfunctions:// Function1Returncode Functionname(ParameterExplain)// Function2Returncode Functionname(ParameterExplain)// ...// FunctionnReturncode Functionname(ParameterExplain)////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////示例3-1文件信息聲明☆
【規(guī)則3.1-1】 文件信息聲明以兩行斜杠開始,以兩行斜杠結(jié)束,每一行都以兩個斜杠開始;☆
【規(guī)則3.1-2】 文件信息聲明包含五個部分,各部分之間以一空行間隔;☆
【規(guī)則3.1-3】 在主要函數(shù)部分描述了文件所包含的主要函數(shù)的聲明信息,如果是頭文件,這一部分是可以省略的。3.1.2頭文件的結(jié)構(gòu)頭文件由三部分內(nèi)容組成:(1)
頭文件開頭處的文件信息聲明(參見示例3-1);(2)
預(yù)處理塊;(3)
函數(shù)和類結(jié)構(gòu)聲明等。假設(shè)頭文件名稱為filesystem.h,頭文件的結(jié)構(gòu)參見示例3-2?!?/p>
【規(guī)則3.2-1】 為了防止頭文件被重復(fù)引用,應(yīng)當(dāng)用ifndef/define/endif結(jié)構(gòu)產(chǎn)生預(yù)處理塊;“#ifndef”或者“#define”后以TAB鍵代替SPACE鍵做空格;如果頭文件名稱是由多個單詞組成,則各單詞間以下劃線“_”連接,例如有頭文件名稱為“filesystem.h”,則定義如下:“#ifndef _FILE_SYSTEM_H_”;☆
【規(guī)則3.2-2】 用#include<filename.h>格式來引用標(biāo)準(zhǔn)庫的頭文件(編譯器將從標(biāo)準(zhǔn)庫目錄開始搜索);☆
【規(guī)則3.2-3】 用#include“filename.h”格式來引用非標(biāo)準(zhǔn)庫的頭文件(編譯器將從用戶的工作目錄開始搜索);☆
【建議3.2-1】 頭文件中只存放“聲明”而不存放“定義”;☆
【建議3.2-1】 頭文件中應(yīng)包含所有定義文件所定義的函數(shù)聲明,如果一個頭文件對應(yīng)多個定義文件,則不同定義文件內(nèi)實現(xiàn)的函數(shù)要分開聲明,并作注釋以解釋所聲明的函數(shù)從屬于那一個定義文件;☆
【建議3.2-3】 宏定義和函數(shù)聲明分離,在兩個頭文件中定義,如果沒有類成員函數(shù),可以將類和結(jié)構(gòu)的定義與函數(shù)聲明分離,也就是說一個頭文件專用于宏定義,一個頭文件專用于類和結(jié)構(gòu)的定義,一個頭文件專用于函數(shù)聲明;☆
【建議3.2-4】 在C++語法中,類的成員函數(shù)可以在聲明的同時被定義,并且自動成為內(nèi)聯(lián)函數(shù)。這雖然會帶來書寫上的方便,但卻造成了風(fēng)格不一致,弊大于利。建議將成員函數(shù)的定義與聲明分開,不論該函數(shù)體有多么小。頭文件的結(jié)構(gòu)如下://文件信息聲明見示例3-1,此處省略。
#ifndef _FILE_SYSTEM_H_ //avoidreferencingthefilefilesystem.hrepeat#define _FILE_SYSTEM_H_#include<math.h> //referencestandardheadfile…#include“myheader.h” //referencenon-standardheadfile…voidFunction1(…); //globalfunctiondeclare…classCBox //classstructuredecalre{…};#endif示例3-2C++/C頭文件的結(jié)構(gòu)
3.1.3定義文件的結(jié)構(gòu)定義文件有三部分內(nèi)容:(1)
定義文件開頭處的文件信息聲明(參見示例3-1);(2)
對一些頭文件的引用;(3)
程序的實現(xiàn)體(包括數(shù)據(jù)和代碼)。假設(shè)定義文件的名稱為filesystem.c,定義文件的結(jié)構(gòu)參見示例3-3。//文件信息聲明見示例3-1,此處省略。
#include“filesystem.h” //referenceaheadfile…//globalfunctionrealizationvoidFunction1(…){…}
//classmemberfunctionrealizationvoidCBox::Draw(…){…}示例3-3C++/C定義文件的結(jié)構(gòu)3.1.4頭文件的作用 早期的編程語言如Basic、Fortran沒有頭文件的概念,C++/C語言的初學(xué)者雖然會用使用頭文件,但常常不明其理。這里對頭文件的作用略作解釋: (1)通過頭文件來調(diào)用庫功能。在很多場合,源代碼不便(或不準(zhǔn))向用戶公布,只要向用戶提供頭文件和二進(jìn)制的庫即可。用戶只需要按照頭文件中的接口聲明來調(diào)用庫功能,而不必關(guān)心接口怎么實現(xiàn)的。編譯器會從庫中提取相應(yīng)的代碼; (2)頭文件能加強(qiáng)類型安全檢查。如果某個接口被實現(xiàn)或被使用時,其方式與頭文件中的聲明不一致,編譯器就會指出錯誤,這一簡單的規(guī)則能大大減輕程序員調(diào)試、改錯的負(fù)擔(dān)。3.1.5目錄結(jié)構(gòu) 如果一個軟件的頭文件數(shù)目比較多(如超過十個),通常應(yīng)將頭文件和定義文件分別保存于不同的目錄,以便于維護(hù)。 例如可將頭文件保存于include目錄,將定義文件保存于source目錄(可以是多級目錄)。如果某些頭文件是私有的,它不會被用戶的程序直接引用,則沒有必要公開其“聲明”。為了加強(qiáng)信息隱藏,這些私有的頭文件可以和定義文件存放于同一個目錄。3.2命名規(guī)則 比較著名的命名規(guī)則當(dāng)推“匈牙利”命名法,該命名規(guī)則的主要思想是“在變量和函數(shù)名中加入前綴以增進(jìn)人們對程序的理解”。例如所有的字符變量均以ch為前綴,若是指針變量則追加前綴p。如果一個變量由ppch開頭,則表明它是指向字符指針的指針。 “匈牙利”法最大的缺點是煩瑣,例如 inti,j,k; floatx,y,z; 倘若采用“匈牙利”命名規(guī)則,則應(yīng)當(dāng)寫成 intiI,iJ,ik;//前綴i表示int類型 floatfX,fY,fZ;//前綴f表示float類型 如此煩瑣的程序會讓絕大多數(shù)程序員無法忍受。 總的說來,沒有一種命名規(guī)則可以讓所有的程序員贊同,且命名規(guī)則對軟件產(chǎn)品而言并不是“成敗悠關(guān)”的事,而且在不同的平臺和不同的環(huán)境下編寫的程序所應(yīng)遵循的規(guī)則也不盡相同,所以我們只是追求制定一種令大多數(shù)項目成員滿意的命名規(guī)則,并在項目中貫徹實施。3.2.1共性原則本節(jié)論述的共性規(guī)則是被大多數(shù)程序員采納的,我們應(yīng)當(dāng)在遵循這些共性規(guī)則的前提下,再擴(kuò)充特定的規(guī)則,如3.2.2節(jié)☆
【規(guī)則3.2.1-1】 標(biāo)識符應(yīng)當(dāng)直觀且可以拼讀,可望文知意,不必進(jìn)行“解碼”;☆
【規(guī)則3.2.1-2】 標(biāo)識符的長度應(yīng)當(dāng)符合“min-length&&max-information”原則;☆
【規(guī)則3.2.1-3】 命名規(guī)則盡量與所采用的操作系統(tǒng)或開發(fā)工具的風(fēng)格保持一致;☆
【規(guī)則3.2.1-4】 程序中不要出現(xiàn)僅靠大小寫區(qū)分的相似的標(biāo)識符?!?/p>
【規(guī)則3.2.1-5】 程序中不要出現(xiàn)標(biāo)識符完全相同的局部變量和全局變量,盡管兩者的作用域不同而不會發(fā)生語法錯誤,但會使人誤解;☆
【規(guī)則3.2.1-6】 變量的名字應(yīng)當(dāng)使用“名詞”或者“形容詞+名詞”;☆
【規(guī)則3.2.1-7】 全局函數(shù)的名字應(yīng)當(dāng)使用“動詞”或者“動詞+名詞”(動賓詞組);☆
【規(guī)則3.2.1-8】 用正確的反義詞組命名具有互斥意義的變量或相反動作的函數(shù)等;☆
【建議3.2.1-9】 盡量避免名字中出現(xiàn)數(shù)字編號,如Value1,Value2等,除非邏輯上的確需要編號;注:3.2.1
標(biāo)識符最好采用英文單詞或其組合,便于記憶和閱讀,切忌使用漢語拼音來命名,程序中的英文單詞一般不要太復(fù)雜,用詞應(yīng)當(dāng)準(zhǔn)確,例如不要把CurrentValue寫成NowValue;3.2.2
標(biāo)示符的長度應(yīng)當(dāng)以最小的長度實現(xiàn)最多信息,一般來說,長名字能更好地表達(dá)含義,但并非長的變量名就一定要比短的變量名要好,此外單字符的名字也是有用的,常見的如i,j,k,m,n,x,y,z等,它們通??捎米骱瘮?shù)內(nèi)的局部變量;3.2.3
不同的操作系統(tǒng)的程序設(shè)計風(fēng)格是不一樣的,例如Windows應(yīng)用程序的標(biāo)識符通常采用“大小寫”混排的方式,如AddChild,而Unix應(yīng)用程序的標(biāo)識符通常采用“小寫加下劃線”的方式,如add_child,別把這兩類風(fēng)格混在一起使用;3.2.2Windows變量命名規(guī)則☆
【規(guī)則3.2.2-1】 變量的命名規(guī)則要求采用“匈牙利法則”,即開頭字母用變量的類型,其余部分用變量的英文意思或其英文意思的縮寫,盡量避免采用中文拼音,要求單詞的第一個字母大寫;即:變量名=變量類型+變量英文意思(或縮寫)變量類型請參見附表1-變量類型表;☆
【規(guī)則3.2.2-2】 類名和函數(shù)名用大寫字母開頭的單詞組合而成;對struct、union、class變量的命名要求定義的類型用大寫,結(jié)構(gòu)采用S開頭,聯(lián)合體采用U開頭,類采用C開頭;例如:structSPoint{ int m_nX; int m_nY;};unionURecordLen{ BYTE m_byRecordNum; BYTE m_byRecordLen;} classCNode { //類成員變量或成員函數(shù) };☆
【規(guī)則3.2.2-3】 指針變量命名的基本原則為:一重指針變量的基本原則為: 變量名=“p”+變量類型前綴+命名對多重指針變量的基本原則為:二重指針:變量名=“pp”+變量類型前綴+命名三重指針: 變量名=“ppp”+變量類型前綴+命名例如一個short*型的變量應(yīng)該表示為pnStart;☆
【規(guī)則3.2.2-4】 全局變量用g_開頭;例如一個全局的長型變量定義為g_lFileNum,即:變量名=g_+變量類型+變量的英文意思(或縮寫);☆
【規(guī)則3.2.2-5】 靜態(tài)變量采用s_開頭;例如一個靜態(tài)的指針變量定義為s_plPrevInst,即:變量名=s_+變量類型+變量的英文意思(或縮寫);☆
【規(guī)則3.2.2-6】 類成員變量采用m_開頭;例如一個長型成員變量定義為m_lCount,即:變量名=m_+變量類型+變量的英文意思(或縮寫);☆
【規(guī)則3.2.2-7】 對const的變量要求在變量的命名規(guī)則前加入c_(若作為函數(shù)的輸入?yún)?shù),可以不加),即:變量名=c_+變量命名規(guī)則,例如:constchar*c_szFileName;☆
【規(guī)則3.2.2-8】 對枚舉類型(enum)中的變量,要求用枚舉變量或其縮寫做前綴,且用下劃線隔離變量名,所有枚舉類型都要用大寫,例如:enum EMDAYS{ EMDAYS_MONDAY; EMDAYS_TUESDAY; };☆
【規(guī)則3.2.2-9】 對常量(包括錯誤的編碼)命名,要求常量名用大寫,常量名用英文意思表示其意思,用下劃線分割單詞,例如:#define CM_7816_OK 0x9000;☆
【規(guī)則3.2.2-10】 為了防止某一軟件庫中的一些標(biāo)識符和其它軟件庫中的沖突,可以為各種標(biāo)識符加上能反映軟件性質(zhì)的前綴。例如三維圖形標(biāo)準(zhǔn)OpenGL的所有庫函數(shù)均以gl開頭,所有常量(或宏定義)均以GL開頭。3.3程序風(fēng)格程序風(fēng)格雖然不會影響程序的功能,但會影響程序的可讀性,追求清晰、美觀,是程序風(fēng)格的重要構(gòu)成因素。3.3.1空行空行起著分隔程序段落的作用??招械皿w(不過多也不過少)將使程序的布局更加清晰??招胁粫速M內(nèi)存,雖然打印含有空行的程序是會多消耗一些紙張,但是值得?!?/p>
【規(guī)則3.3.1-1】 在每個類聲明之后、每個函數(shù)定義結(jié)束之后都要加空行。參見示例3.3.1(a);☆
【規(guī)則3.3.1-2】 在一個函數(shù)體內(nèi),邏揖上密切相關(guān)的語句之間不加空行,其它地方應(yīng)加空行分隔。參見示例3.3.1(b);
//blanklinevoidFunction1(…){…}//blanklinevoidFunction2(…){…}//blanklinevoidFunction3(…){…}
//blanklinewhile(condition){ statement1; //blankline if(condition) { statement2; } else { statement3; }//blankline statement4;}示例3.3.1(a)函數(shù)之間的空行示例3.3.1(b)函數(shù)內(nèi)部的空行
3.3.2代碼行☆
【規(guī)則3.3.2-1】 一行代碼只做一件事情,如只定義一個變量,或只寫一條語句,這樣的代碼容易閱讀,并且方便于寫注釋;☆
【規(guī)則3.3.2-2】 if、for、while、do等語句自占一行,執(zhí)行語句不得緊跟其后,不論執(zhí)行語句有多少都要加{},這樣可以防止書寫失誤;☆
【規(guī)則3.3.2-3】 if、for、while、do等語句的“{”要單獨占用一行;☆
【建議3.3.2-1】 所有函數(shù)內(nèi)的變量都在函數(shù)開始處定義;☆
【建議3.3.2-2】 盡可能在定義變量的同時初始化該變量(就近原則),如果變量的引用處和其定義處相隔比較遠(yuǎn),變量的初始化很容易被忘記。如果引用了未被初始化的變量,可能會導(dǎo)致程序錯誤,本建議可以減少隱患。示例3.3.2(a)為風(fēng)格良好的代碼行,示例3.3.2(b)為風(fēng)格不良的代碼行。
intnWidth; //widthintnHeight; //heightintnDepth; //depth
intnWidth,nHight,nDepth;//width,height,depth
x=a+b;y=c+d;z=e+f;X=a+b;y=c+d;z=e+f;
if(nWidth<nHight){ DoSomething();}if(nWidth<nHight)DoSomething();for(initialization;condition;update){DoSomething();}//blanklineOther();
for(initialization;condition;update)DoSomething();Other();
示例3.3.2(a)風(fēng)格良好的代碼行示例3.3.2(b)風(fēng)格不良的代碼行3.3.3代碼行內(nèi)的空格☆
【規(guī)則3.3.3-1】 關(guān)鍵字之后要留空格,象const、virtual、inline、case等關(guān)鍵字之后至少要留一個空格,否則無法辨析關(guān)鍵字,象if、for、while等關(guān)鍵字之后應(yīng)留一個空格再跟左括號‘(’,以突出關(guān)鍵字;☆
【規(guī)則3.3.3-2】 函數(shù)名之后不要留空格,緊跟左括號‘(’,以與關(guān)鍵字區(qū)別;☆
【規(guī)則3.3.3-3】 ‘(’向后緊跟,‘)’、‘,’、‘;’向前緊跟,緊跟處不留空格;☆
【規(guī)則3.3.3-4】 ‘,’之后要留空格,如Function(x,y,z),如果‘;’不是一行的結(jié)束符號,其后要留空格,如for(initialization;condition;update);☆
【規(guī)則3.3.3-5】 賦值操作符、比較操作符、算術(shù)操作符、邏輯操作符、位域操作符,如“=”、“+=”“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后應(yīng)當(dāng)加空格;☆
【規(guī)則3.3.3-6】 一元操作符如“!”、“~”、“++”、“--”、“&”(地址運算符)等前后不加空格;☆
【規(guī)則3.3.3-7】 象“[]”、“.”、“->”這類操作符前后不加空格;☆
【建議3.3.3-1】 對于表達(dá)式比較長的for語句和if語句,為了緊湊起見可以適當(dāng)?shù)厝サ粢恍┛崭?,如for(i=0;i<10;i++)和if((a<=b)&&(c<=d))
voidFunc1(intx,inty,intz);//favorablestylevoidFunc1(intx,inty,intz);//illstyleif(year>=2000)//favorablestyleif(year>=2000)//illstyleif((a>=b)&&(c<=d))//favorablestyleif(a>=b&&c<=d)//illstylefor(i=0;i<10;i++)//favorablestylefor(i=0;i<10;i++)//illstylefor(i=0;I<10;i++)//favorablestylex=a<b?a:b;//favorablestylex=a<b?a:b;//illstyleint*x=&y;//favorablestyleint*x=&y;//illstylearray[5]=0;//Donotusearray[5]=0;a.Function();//Donotusea.Function();b->Function();//Donotuseb->Function();
示例3.3.3代碼行內(nèi)的空格
3.3.4對齊☆
【規(guī)則3.3.4-1】 程序的分界符‘{’和‘}’應(yīng)獨占一行并且位于同一列,同時與引用它們的語句左對齊;☆
【規(guī)則3.3.4-2】 {}之內(nèi)的代碼塊在‘{’右邊數(shù)格處左對齊;☆
【規(guī)則3.3.4.3】 代碼的的對齊采用TAB鍵而不采用空格鍵對齊,一般TAB鍵設(shè)置為向后空4個空格。
示例3.3.4(a)為風(fēng)格良好的對齊,示例3.3.4(b)為風(fēng)格不良的對齊。
voidFunction(intx){…//programcode}
voidFunction(intx){…//programcode}
if(condition){…//programcode}else{…//programcode}if(condition){…//programcode}else{…//programcode}for(initialization;condition;update){…//programcode}for(initialization;condition;update){…//programcode}While(condition){…//programcode}while(condition){…//programcode}如果出現(xiàn)嵌套的{},則使用縮進(jìn)對齊,如: { … { … } …}
示例3.3.4(a)風(fēng)格良好的對齊示例3.3.4(b)風(fēng)格不良的對齊3.3.5長行拆分☆
【規(guī)則3.3.5-1】 代碼行最大長度宜控制在70至80個字符以內(nèi);☆
【規(guī)則3.3.5-2】 長表達(dá)式要在低優(yōu)先級操作符處拆分成新行,操作符放在新行之首(以便突出操作符),拆分出的新行要進(jìn)行適當(dāng)?shù)目s進(jìn),使排版整齊,語句可讀。
if((very_longer_variable1>=very_longer_variable12)&&(very_longer_variable3<=very_longer_variable14)&&(very_longer_variable5<=very_longer_variable16)){DoSomething();}virtualCMatrixCMultiplyMatrix(CMatrixleftMatrix,CMatrixrightMatrix);
for(very_longer_initialization; very_longer_condition; very_longer_update){ DoSomething();}示例3.3.5長行的拆分3.3.6修飾符的位置修飾符*和&應(yīng)該靠近數(shù)據(jù)類型還是該靠近變量名,是個有爭議的活題,若將修飾符*靠近數(shù)據(jù)類型,例如:int*x;從語義上講此寫法比較直觀,即x是int類型的指針,上述寫法的弊端是容易引起誤解,例如:int*x,y;此處y容易被誤解為指針變量。雖然將x和y分行定義可以避免誤解,但并不是人人都愿意這樣做?!?/p>
【規(guī)則3.3.6-1】 應(yīng)當(dāng)將修飾符*和&緊靠變量名;3.3.7注釋C語言的注釋符為“/*…*/”。C++語言中,程序塊的注釋常采用“/*…*/”,行注釋一般采用“//…”。注釋通常用于:(1)版本、版權(quán)聲明;(2)函數(shù)接口說明;(3)重要的代碼行或段落提示。雖然注釋有助于理解代碼,但注意不可過多地使用注釋。參見示例3.3.7。
☆
【規(guī)則3.3.7-1】 注釋是對代碼的“提示”,而不是文檔,程序中的注釋不可喧賓奪主,注釋太多了會讓人眼花繚亂,注釋的花樣要少;☆
【規(guī)則3.3.7-2】 如果代碼本來就是清楚的,則不必加注釋;例如i++; //i加1,多余的注釋☆
【規(guī)則3.3.7-3】 邊寫代碼邊注釋,修改代碼同時修改相應(yīng)的注釋,以保證注釋與代碼的一致性,不再有用的注釋要刪除;☆
【規(guī)則3.3.7-4】 注釋應(yīng)當(dāng)準(zhǔn)確、易懂,防止注釋有二義性,錯誤的注釋不但無益反而有害;☆
【規(guī)則3.3.7-5】 盡量避免在注釋中使用縮寫,特別是不常用縮寫;☆
【規(guī)則3.3.7-6】 注釋的位置應(yīng)與被描述的代碼相鄰,可以放在代碼的上方或右方,不可放在下方;☆
【規(guī)則3.3.7-8】 當(dāng)代碼比較長,特別是有多重嵌套時,應(yīng)當(dāng)在一些段落的結(jié)束處加注釋,便于閱讀;☆
【建議3.3.7-9】 對于多行代碼的注釋,盡量不采用“/*...*/”,而采用多行“//”注釋,這樣雖然麻煩,但是在做屏蔽調(diào)試時不用查找配對的“/*...*/”。
//////////////////////////////////////////////////////////////////////Functioncapacity://Parameterdeclare://Returnvalue:////////////////////////////////////////////////////////////////////voidFunction(floatx,floaty,floatz){…}
if(…){…while(…){…}//endofwhile…}//endofif示例3.3.7程序的注釋3.7.1文件頭的注釋 文件頭的注釋請參見3.1,文件頭的注釋是以兩行斜杠開始,以兩行斜杠結(jié)束(以區(qū)別于函數(shù)的注釋)。3.7.2函數(shù)頭的注釋一般說來每個函數(shù)都應(yīng)該做詳細(xì)的注釋,函數(shù)頭的注釋是以一行斜杠開始,以一行斜杠結(jié)束,注釋的內(nèi)容包括“功能”,“參數(shù)”,“返回值”,“設(shè)計思想”,“調(diào)用函數(shù)”,“日期”,“修改記錄”等幾個方面,函數(shù)頭的注釋格式如下:////////////////////////////////////////////////////////////////////////////////////////////////Functioncapacity: Describethefunctioncapacity//Parameterdeclare:// parameter1: Describethefunctionofparameter(input/outputparameter)// parameter2: Describethefunctionofparameter(input/outputparameter)// //Returnvalue:Describethepossiblereturnvalue//Designedidea:Describedesignedideaaboutthefunction//Author: //Creationdate:Creationdate(YY-MM-DD)//Transferredfunction: Listthesub-functioninthefunction//Modificationrecord:// (一)Mender1: Modifieddate: modifiedcontent//////////////////////////////////////////////////////////////////////////////////////////////
3.4函數(shù)設(shè)計 函數(shù)是C++/C程序的基本功能單元,其重要性不言而喻。函數(shù)設(shè)計的細(xì)微缺點很容易導(dǎo)致該函數(shù)被錯用,所以光使函數(shù)的功能正確是不夠的。本章重點論述函數(shù)的接口設(shè)計和內(nèi)部實現(xiàn)的一些規(guī)則。 函數(shù)接口的兩個要素是參數(shù)和返回值。C語言中,函數(shù)的參數(shù)和返回值的傳遞方式有兩種:值傳遞(passbyvalue)和指針傳遞(passbypointer)。C++語言中多了引用傳遞(passbyreference)。由于引用傳遞的性質(zhì)象指針傳遞,而使用方式卻象值傳遞,初學(xué)者常常迷惑不解,容易引起混亂,請先閱讀3.4.6節(jié)“引用與指針的比較”。3.4.1參數(shù)的規(guī)則☆
【規(guī)則3.4.1-1】 參數(shù)的書寫要完整,不要貪圖省事只寫參數(shù)的類型而省略參數(shù)名字,如果函數(shù)沒有參數(shù),則用void填充;例如:voidSetValue(intnWidth,intnHeight); //良好的風(fēng)格voidSetValue(int,int); //不良的風(fēng)格floatGetValue(void); //良好的風(fēng)格floatGetValue(); //不良的風(fēng)格☆
【規(guī)則3.4.1-2】 參數(shù)命名要恰當(dāng),順序要合理;例如編寫字符串拷貝函數(shù)StringCopy,它有兩個參數(shù),如果把參數(shù) 名字起為str1和str2,例如:voidStringCopy(char*str1,char*str2);那么我們很難搞清楚究竟是把str1拷貝到str2中,還是剛好倒過來,可以把參數(shù)名字起得更有意義,如叫strSource和strDestination。這樣從名字上就可以看出應(yīng)該把strSource拷貝到strDestination。還有一個問題,這兩個參數(shù)那一個該在前那一個該在后?參數(shù)的順序要遵循程序員的習(xí)慣。一般地,應(yīng)將目的參數(shù)放在前面,源參數(shù)放在后面。如果將函數(shù)聲明為:voidStringCopy(char*strSource,char*strDestination);別人在使用時可能會不假思索地寫成如下形式:charstr[20];StringCopy(str,“HelloWorld”); //參數(shù)順序顛倒
☆
【規(guī)則3.4.1-3】 如果參數(shù)是指針,且僅作輸入用,則應(yīng)在類型前加const,以防止該指針在函數(shù)體內(nèi)被意外修改。例如:voidStringCopy(char*strDestination,constchar*strSource);☆
【規(guī)則3.4.1-4】 如果輸入?yún)?shù)以值傳遞的方式傳遞對象,則宜改用“const&”方式來傳遞,這樣可以省去臨時對象的構(gòu)造和析構(gòu)過程,從而提高效率;☆
【建議3.4.1-1】 避免函數(shù)有太多的參數(shù),參數(shù)個數(shù)盡量控制在5個以內(nèi)。如果參數(shù)太多,在使用時容易將參數(shù)類型或順序搞錯;☆
【建議3.4.1-2】 盡量不要使用類型和數(shù)目不確定的參數(shù);C標(biāo)準(zhǔn)庫函數(shù)printf是采用不確定參數(shù)的典型代表,其原型為:intprintf(constchat*format[,argument]…);這種風(fēng)格的函數(shù)在編譯時喪失了嚴(yán)格的類型安全檢查。3.4.2返回值的規(guī)則☆
【規(guī)則3.4.2-1】 不要省略返回值的類型;C語言中,凡不加類型說明的函數(shù),一律自動按整型處理,這樣做不會有什么好處,卻容易被誤解為void類型;C++語言有很嚴(yán)格的類型安全檢查,不允許上述情況發(fā)生。由于C++程序可以調(diào)用C函數(shù),為了避免混亂,規(guī)定任何C++/C函數(shù)都必須有類型。如果函數(shù)沒有返回值,那么應(yīng)聲明為void類型☆
【規(guī)則3.4.2-2】 函數(shù)名字與返回值類型在語義上不可沖突;違反這條規(guī)則的典型代表是C標(biāo)準(zhǔn)庫函數(shù)getchar。例如:charc;c=getchar();if(c==EOF)…按照getchar名字的意思,將變量c聲明為char類型是很自然的事情。但不幸的是getchar的確不是char類型,而是int類型,其原型如下:intgetchar(void);由于c是char類型,取值范圍是[-128,127],如果宏EOF的值在char的取值范圍之外,那么if語句將總是失敗,這種“危險”人們一般哪里料得到!導(dǎo)致本例錯誤的責(zé)任并不在用戶,是函數(shù)getchar誤導(dǎo)了使用者☆
【規(guī)則3.4.2-3】 不要將正常值和錯誤標(biāo)志混在一起返回。正常值用輸出參數(shù)獲得,而錯誤標(biāo)志用return語句返回;☆
【建議3.4.2-1】 有時候函數(shù)原本不需要返回值,但為了增加靈活性如支持鏈?zhǔn)奖磉_(dá),可以附加返回值;例如字符串拷貝函數(shù)strcpy的原型:char*strcpy(char*strDest,constchar*strSrc);strcpy函數(shù)將strSrc拷貝至輸出參數(shù)strDest中,同時函數(shù)的返回值又是strDest。這樣做并非多此一舉,可以獲得如下靈活性:charstr[20];intnLength=strlen(strcpy(str,“HelloWorld”));☆
【建議3.4.2-2】 如果函數(shù)的返回值是一個對象,有些場合用“引用傳遞”替換“值傳遞”可以提高效率。而有些場合只能用“值傳遞”而不能用“引用傳遞”,否則會出錯;對于建議3.4.2-2,如果函數(shù)的返回值是一個對象,有些場合用“引用傳遞”替換“值傳遞”可以提高效率,而有些場合只能用“值傳遞”而不能用“引用傳遞”,否則會出錯,例如:classString{… //賦值函數(shù) String&operate=(constString&other); //相加函數(shù),如果沒有friend修飾則只許有一個右側(cè)參數(shù)friend Stringoperate+(constString&s1,constString&s2);private: char*m_data;};String的賦值函數(shù)operate=的實現(xiàn)如下:String&String::operate=(constString&other){ if(this==&other) return*this; deletem_data; m_data=newchar[strlen(other.data)+1]; strcpy(m_data,other.data); return*this; //返回的是*this的引用,無需拷貝過程}對于賦值函數(shù),應(yīng)當(dāng)用“引用傳遞”的方式返回String對象。如果用“值傳遞”的方式,雖然功能仍然正確,但由于return語句要把*this拷貝到保存返回值的外部存儲單元之中,增加了不必要的開銷,降低了賦值函數(shù)的效率。例如: Stringa,b,c; … a=b; //如果用“值傳遞”,將產(chǎn)生一次*this拷貝 a=b=c; //如果用“值傳遞”,將產(chǎn)生兩次*this拷貝
String的相加函數(shù)operate+的實現(xiàn)如下:Stringoperate+(constString&s1,constString&s2){ Stringtemp; deletetemp.data; //temp.data是僅含‘\0’的字符串 temp.data=newchar[strlen(s1.data)+strlen(s2.data)+1]; strcpy(temp.data,s1.data); strcat(temp.data,s2.data); returntemp; }
對于相加函數(shù),應(yīng)當(dāng)用“值傳遞”的方式返回String對象。如果改用“引用傳遞”,那么函數(shù)返回值是一個指向局部對象temp的“引用”。由于temp在函數(shù)結(jié)束時被自動銷毀,將導(dǎo)致返回的“引用”無效。例如: c=a+b;此時a+b并不返回期望值,c什么也得不到,流下了隱患。3.4.3函數(shù)內(nèi)部實現(xiàn)的規(guī)則不同功能的函數(shù)其內(nèi)部實現(xiàn)各不相同,看起來似乎無法就“內(nèi)部實現(xiàn)”達(dá)成一致的觀點。但根據(jù)經(jīng)驗,我們可以在函數(shù)體的“入口處”和“出口處”從嚴(yán)把關(guān),從而提高函數(shù)的質(zhì)量。
☆
【規(guī)則3.4.3-1】 在函數(shù)體的“入口處”,對參數(shù)的有效性進(jìn)行檢查;很多程序錯誤是由非法參數(shù)引起的,我們應(yīng)該充分理解并正確使用“斷言”(assert)來防止此類錯誤。詳見4.5節(jié)“使用斷言”☆
【規(guī)則3.4.3-2】 在函數(shù)體的“出口處”,對return語句的正確性和效率進(jìn)行檢查;注意事項如下:(1)
return語句不可返回指向“棧內(nèi)存”的“指針”或者“引用”,因為該內(nèi)存在函數(shù)體結(jié)束時被自動銷毀,例如: char*Func(void) { charstr[]=“helloworld”; //str的內(nèi)存位于棧上 … returnstr; //將導(dǎo)致錯誤 }(2)
要搞清楚返回的究竟是“值”、“指針”還是“引用”;(3)
如果函數(shù)返回值是一個對象,要考慮return語句的效率,例如: returnString(s1+s2);這是臨時對象的語法,表示“創(chuàng)建一個臨時對象并返回它”,不要以為它與“先創(chuàng)建一個局部對象temp并返回它的結(jié)果”是等價的,如 Stringtemp(s1+s2); returntemp;實質(zhì)不然,上述代碼將發(fā)生三件事。 首先,temp對象被創(chuàng)建,同時完成初始化; 然后拷貝構(gòu)造函數(shù)把temp拷貝到保存返回值的外部存儲單元中; 最后,temp在函數(shù)結(jié)束時被銷毀(調(diào)用析構(gòu)函數(shù))。然而“創(chuàng)建一個臨時對象并返回它”的過程是不同的,編譯器直接把臨時對象創(chuàng)建并初始化在外部存儲單元中,省去了拷貝和析構(gòu)的化費,提高了效率。類似地,我們不要將 returnint(x+y); //創(chuàng)建一個臨時變量并返回它寫成 inttemp=x+y; returntemp;由于內(nèi)部數(shù)據(jù)類型如int,float,double的變量不存在構(gòu)造函數(shù)與析構(gòu)函數(shù),雖然該“臨時變量的語法”不會提高多少效率,但是程序更加簡潔易讀。3.4.4其它建議☆
【建議3.4.4-1】 函數(shù)的功能要單一,不要設(shè)計多用途的函數(shù);☆
【建議3.4.4-2】 函數(shù)體的規(guī)模要小,盡量控制在150行代碼之內(nèi);☆
【建議3.4.4-3】 盡量避免函數(shù)帶有“記憶”功能。相同的輸入應(yīng)當(dāng)產(chǎn)生相同的輸出帶有“記憶”功能的函數(shù),其行為可能是不可預(yù)測的,因為它的行為可能取決于某種“記憶狀態(tài)”。這樣的函數(shù)既不易理解又不利于測試和維護(hù)。在C/C++語言中,函數(shù)的static局部變量是函數(shù)的“記憶”存儲器。建議盡量少用static局部變量,除非必需。☆
【建議3.4.4-4】 不僅要檢查輸入?yún)?shù)的有效性,還要檢查通過其它途徑進(jìn)入函數(shù)體內(nèi)的變量的有效性,例如全局變量、文件句柄等;☆
【建議3.4.4-5】 用于出錯處理的返回值一定要清楚,讓使用者不容易忽視或誤解錯誤情況。3.4.5使用斷言程序一般分為Debug版本和Release版本,Debug版本用于內(nèi)部調(diào)試,Release版本發(fā)行給用戶使用。斷言assert是僅在Debug版本起作用的宏,它用于檢查“不應(yīng)該”發(fā)生的情況。示例4.5是一個內(nèi)存復(fù)制函數(shù)。在運行過程中,如果assert的參數(shù)為假,那么程序就會中止(一般地還會出現(xiàn)提示對話,說明在什么地方引發(fā)了assert)。
void*memcpy(void*pvTo,constvoid*pvFrom,size_tsize){ assert((pvTo!=NULL)&&(pvFrom!=NULL)); //使用斷言 byte*pbTo=(byte*)pvTo; //防止改變pvTo的地址 byte*pbFrom=(byte*)pvFrom; //防止改變pvFrom的地址 while(size-->0) *pbTo++=*pbFrom++; returnpvTo;}示例3.4.5復(fù)制不重疊的內(nèi)存塊
assert不是一個倉促拼湊起來的宏。為了不在程序的Debug版本和Release版本引起差別,assert不應(yīng)該產(chǎn)生任何副作用。所以assert不是函數(shù),而是宏。程序員可以把a(bǔ)ssert看成一個在任何系統(tǒng)狀態(tài)下都可以安全使用的無害測試手段。如果程序在assert處終止了,并不是說含有該assert的函數(shù)有錯誤,而是調(diào)用者出了差錯,assert可以幫助我們找到發(fā)生錯誤的原因。
☆
【規(guī)則3.4.5-1】 使用斷言捕捉不應(yīng)該發(fā)生的非法情況,不要混淆非法情況與錯誤情況之間的區(qū)別,后者是必然存在的并且是一定要作出處理的;☆
【規(guī)則3.4.5-2】 在函數(shù)的入口處,使用斷言檢查參數(shù)的有效性(合法性);☆
【建議3.4.5-1】 在編寫函數(shù)時,要進(jìn)行反復(fù)的考查,并且自問:“我打算做哪些假定?”一旦確定了的假定,就要使用斷言對假定進(jìn)行檢查;☆
【建議3.4.5-2】 一般教科書都鼓勵程序員們進(jìn)行防錯設(shè)計,但要記住這種編程風(fēng)格可能會隱瞞錯誤。當(dāng)進(jìn)行防錯設(shè)計時,如果“不可能發(fā)生”的事情的確發(fā)生了,則要使用斷言進(jìn)行報警。3.4.6引用與指針的比較引用是C++中的概念,初學(xué)者容易把引用和指針混淆一起。一下程序中,n是m的一個引用(reference),m是被引用物(referent)。 intm; int&n=m;n相當(dāng)于m的別名(綽號),對n的任何操作就是對m的操作。所以n既不是m的拷貝,也不是指向m的指針,其實n就是m它自己。引用的一些規(guī)則如下:(1)
引用被創(chuàng)建的同時必須被初始化(指針則可以在任何時候被初始化);(2)
不能有NULL引用,引用必須與合法的存儲單元關(guān)聯(lián)(指針則可以是NULL);(3)
一旦引用被初始化,就不能改變引用的關(guān)系(指針則可以隨時改變所指的對象)。 以下示例程序中,k被初始化為i的引用。語句k=j并不能將k修改成為j的引用,只是把k的值改變成為6。由于k是i的引用,所以i的值也變成了6。 inti=5; intj=6; int&k=i; k=j; //k和i的值都變成了6; 上面的程序看起來象在玩文字游戲,沒有體現(xiàn)出引用的價值。引用的主要功能是傳遞函數(shù)的參數(shù)和返回值。C++語言中,函數(shù)的參數(shù)和返回值的傳遞方式有三種:值傳遞、指針傳遞和引用傳遞。 以下是“值傳遞”的示例程序。由于Func1函數(shù)體內(nèi)的x是外部變量n的一份拷貝,改變x的值不會影響n,所以n的值仍然是0。 voidFunc1(intx){ x=x+10;}…intn=0; Func1(n); cout<<“n=”<<n<<endl; //n=0 以下是“指針傳遞”的示例程序。由于Func2函數(shù)體內(nèi)的x是指向外部變量n的指針,改變該指針的內(nèi)容將導(dǎo)致n的值改變,所以n的值成為10。 voidFunc2(int*x){ (*x)=(*x)+10;}…intn=0; Func2(&n); cout<<“n=”<<n<<endl; //n=10
以下是“引用傳遞”的示例程序。由于Func3函數(shù)體內(nèi)的x是外部變量n的引用,x和n是同一個東西,改變x等于改變n,所以n的值成為10。 voidFunc3(int&x){ x=x+10;}…intn=0; Func3(n); cout
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 借款商鋪質(zhì)押合同范例
- 交易押金合同范例
- 散件組裝采購合同范例
- 借款質(zhì)押保證合同范例
- 工資薪酬制度合同范例
- 商場意向合同范例
- 旅游國內(nèi)電子合同范例
- 培訓(xùn)學(xué)校培訓(xùn)合同范例
- 加盟項目代理合同范例
- 買房收款合同范例
- 2022-2023學(xué)年廣東省深圳市羅湖區(qū)八年級(上)期末歷史試卷
- 企業(yè)員工心理健康管理培訓(xùn)一
- 國家開放大學(xué)電大??啤督ㄖこ添椖抗芾怼?024期末試題及答案
- GB/T 44823-2024綠色礦山評價通則
- 2025年全年日歷表(每月一張共12張)
- DG-TJ08-2433A-2023 外墻保溫一體化系統(tǒng)應(yīng)用技術(shù)標(biāo)準(zhǔn)(預(yù)制混凝土反打保溫外墻)
- 小學(xué)校本課程-【海洋教育】尋覓沉睡的寶船教學(xué)設(shè)計學(xué)情分析教材分析課后反思
- 國家開放大學(xué)《土木工程力學(xué)(本)》形考作業(yè)1-5參考答案
- 插床設(shè)計計算說明書
- 地球的地殼元素豐度列表
- 質(zhì)量環(huán)保部采制樣室“8-26”機(jī)械傷害事故
評論
0/150
提交評論