14年課題相關(guān)編程和范例_第1頁
14年課題相關(guān)編程和范例_第2頁
14年課題相關(guān)編程和范例_第3頁
14年課題相關(guān)編程和范例_第4頁
14年課題相關(guān)編程和范例_第5頁
已閱讀5頁,還剩53頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、目錄排版注釋標(biāo)識符命名可讀性變量、結(jié)構(gòu)函數(shù)、過程可測性程序效率質(zhì)量保證222836404450525356789代碼編輯、編譯、代碼測試、宏1 排版1-1:程序塊要采用縮進(jìn)風(fēng)格編寫,縮進(jìn)的空格數(shù)為4個。說明:對于由開發(fā)工具自動生成的代碼可以有不一致。1-2:相對獨(dú)立的程序塊之間、變量說明之后必須加空行。示例:如下例子不符合規(guī)范。if (!valid_ni(ni). / program codereprep_ind =_ni =_dataindex.rep_dataindex.ni;_index;應(yīng)如下書寫if (!valid_ni(ni). / program codereprep_ind =

2、_ni =_dataindex.rep_dataindex.ni;_index;1-3:較長的語句(80字符)要分成多行書寫,長表達(dá)式要在低優(yōu)先級操作符處劃分新行,操作符放在新行之首,劃分出的新行要進(jìn)行適當(dāng)?shù)目s進(jìn),使排版整齊,語句可讀。示例:perm_count_msg.head.len =+ SNO7_TO_S_PERM_COUNT_LEN_SIZE_PER_FRAM * sizeof( _UL );act_task_tableframe_id *S_TASK_CHECK_NUMBER + index.occupied= s_poiindex.occupied;act_task_tablet

3、askno.duration_true_or_false= SYS_get_s_sistic_se( s_item );report_or_not_flag = (taskno MAX_ACT_TASK_NUMBER)& (n7s_s_item_valid (s_item)& (act_task_tabletaskno.result_data != 0);1-4:循環(huán)、判斷等語句中若有較長的表達(dá)式或語句,則要進(jìn)行適應(yīng)的劃分,長表達(dá)式要在低優(yōu)先級操作符處劃分新行,操作符放在新行之首。示例:if (taskno max_act_task_number)& (n7s_s_item_valid (s_

4、item). / program codefor (i = 0, j = 0; (i BufferKeywordword_index.word_length) & (j NewKeyword.word_length); i+, j+). / program codefor (i =(i i+,0, j = 0;_word_length) & (j ),后不應(yīng)加空格。說明:采用這種松散方式編寫代碼的目的是使代碼更加清晰。由于留空格所產(chǎn)生的清晰性是相對的,所以,在已經(jīng)非常清晰的語句中沒有必要再留空格,如果語句已足夠清晰則括號內(nèi)側(cè)(即左括號后面和右括號前面)不需要加空格,多重括號間不必加空格,因為在

5、 C/C+語言中括號已經(jīng)是最清晰的標(biāo)志了。在長語句中,如果需要加的空格非常多,那么應(yīng)該保持整體清晰,而在局部不加空格。給操作符留空格時不要連續(xù)留兩個以上空格。示例:(1) 逗號、分號只在后面加空格。a, b, c;(2)比較操作符, 賦值操作符=、 +=,算術(shù)操作符+、%,邏輯操作符&、&,位域操作符= MAX_TIME_VALUE)a aa= b + c;*= 2;= b 2;(3)!、+、-、&(地址運(yùn)算符)等單目操作符前后不加空格。*p = a;/ 內(nèi)容操作*與內(nèi)容之間flag = !isEmpty; / 非操作!與內(nèi)容之間p = &mem;i+;/ 地址操作& 與內(nèi)容之間/ +,-與內(nèi)

6、容之間(4)-、.前后不加空格。p-id =;/ -指針前后不加空格(5) if、for、while、switch 等與后面的括號間應(yīng)加空格,使 if 等關(guān)鍵字更為突出、明顯。if (a = b & c d)1-1:一行程序以小于80字符為宜,不要寫得過長。2 注釋2-1:一般情況下,源程序有效注釋量必須在20以上。說明:注釋的原則是有助于對程序的閱讀理解,在該加的地方都加了,注釋不宜太多也不能太少,注釋語言必須準(zhǔn)確、易懂、簡潔。2-2:說明性文件(如頭文件.h文件、.inc文件、.def文件、編譯說明文件.cfg等)頭部應(yīng)進(jìn)行注釋,注釋必須列權(quán)說明、版本號、生成日期、作者、內(nèi)容、功能、與其它

7、文件的關(guān)系、修改日志等,頭文件的注釋中還應(yīng)有函數(shù)功能簡明。示例:下面這段頭文件的頭注釋比較標(biāo)準(zhǔn),當(dāng)然,并不局限于此格式,但上述信息建議要包含在內(nèi)。/*Copyright (C), 1988-1999,Tech. Co.,./ 文件名File name: Author:Description:Ver:Date: / 作者、版本及完成日期/ 用于詳細(xì)說明此程序文件完成的主要功能,與其他模塊/ 或函數(shù)的接口,輸出值、取值范圍、含義及參數(shù)間的控/ 制、順序、獨(dú)立或依賴等關(guān)系/ 其它內(nèi)容的說明Others:Function List: / 主要函數(shù)列表,每條1. .應(yīng)包括函數(shù)名及功能簡明/ 修改歷史列表

8、,每條修改應(yīng)包括修改日期、修改History:/ 者及修改內(nèi)容簡述1. Date:Author:Modification: 2. .*/2-3:源文件頭部應(yīng)進(jìn)行注釋,列主要函數(shù)及其功能、修改日志等。權(quán)說明、版本號、生成日期、作者、模塊目的/功能、示例:下面這段源文件的頭注釋比較標(biāo)準(zhǔn),當(dāng)然,并不局限于此格式,但上述信息建議要包含在內(nèi)。/*CopyrightFileName: Author:(C), 1988-1999,test.cppTech. Co.,.Ver:Date:Description:/ 模塊描述/ 版本信息/ 主要函數(shù)及其功能Ver:FunctionList:1.History:/

9、 歷史修改 David96/10/121.0build this moudle*/說明:Description 一項描述本文件的內(nèi)容、功能、內(nèi)部各部分之間的關(guān)系及本文件與其它文件關(guān)系等。History 是修改歷史者及修改內(nèi)容簡述。列表,每條修改應(yīng)包括修改日期、修改2-4:函數(shù)頭部應(yīng)進(jìn)行注釋,列出:函數(shù)的目的/功能、輸入?yún)?shù)、輸出參數(shù)、返回值、調(diào)用關(guān)系(函數(shù)、表)等。示例:下面這段函數(shù)的注釋比較標(biāo)準(zhǔn),當(dāng)然,并不局限于此格式,但上述信息建議要包含在內(nèi)。/*/ 函數(shù)名稱/ 函數(shù)功能、性能等的描述/ 被本函數(shù)調(diào)用的函數(shù)/ 調(diào)用本函數(shù)的函數(shù)Function: Description: Calls:Cal

10、led By:Table Acsed: / 被的表(此項僅對于牽扯到數(shù)據(jù)庫操作的程序)Table Updated: / 被修改的表(此項僅對于牽扯到數(shù)據(jù)庫操作的程序)Input:/ 輸入?yún)?shù)說明,包括每個參數(shù)的作/ 用、取值說明及參數(shù)間關(guān)系。/ 對輸出參數(shù)的說明。/ 函數(shù)返回值的說明/ 其它說明Output:Return: Others:*/2-5:邊寫代碼邊注釋,修改代碼同時修改相應(yīng)的注釋,以保證注釋與代碼的一致性。不再有用的注釋要刪除。2-6:注釋的內(nèi)容要清楚、明了,含義準(zhǔn)確,防止注釋二義性。說明:錯誤的注釋不但無益反而有害。規(guī)則2-7:避免在注釋中使用縮寫,特別是非常用縮寫。說明:在使用

11、縮寫時或之前,應(yīng)對縮寫進(jìn)行必要的說明。2-8:注釋應(yīng)與其描述的代碼相近,對代碼的注釋應(yīng)放在其上方或右方(對單條語句的注釋)相鄰位置,不可放在下面,如放于上方則需與其上面的代碼用空行隔開。示例:如下例子不符合規(guī)范。例 1:/* get replicate sub system indexand net indicator*/reprep_ind =_ni =_dataindex.rep_dataindex.ni;_index;例 2:rep rep_ind =_ni =_dataindex.rep_dataindex.ni;_index;/* get replicate sub system i

12、ndexand net indicator*/應(yīng)如下書寫/* get replicate sub system indexand net indicator_index;*/reprep_ind =_ni =_dataindex.rep_dataindex.ni;2-9:對于所有有物理含義的變量、常量,如果其命名不是充分自注釋的,在時都必須加以注釋,說明其物理含義。變量、常量、宏的注釋應(yīng)放在其上方相鄰位置或右方。示例:/* active sistik number */#define MAX_ACT_TASK_NUMBER 1000#define MAX_ACT_TASK_NUMBER 100

13、0 /* active sistik number */2-10:數(shù)據(jù)結(jié)構(gòu)(包括數(shù)組、結(jié)構(gòu)、類、枚舉等),如果其命名不是充分自注釋的,必須加以注釋。對數(shù)據(jù)結(jié)構(gòu)的注釋應(yīng)放在其上方相鄰位置,不可放在下面;對結(jié)構(gòu)中的每個域的注在此域的右方。示例:可按如下形式說明枚舉/數(shù)據(jù)/聯(lián)合結(jié)構(gòu)。/* s enum Serface with s_USER_PRIMITIVEusrimitive message name */N_UNITDATA_IND, /* snotify suser unit dome */can not */N_NOTICE_IND,/* snotify user the No.7 net

14、work/* transmisthis message */N_UNITDATA_REQ, /* susers unit daransmisrequest*/;2-11:全局變量要有較詳細(xì)的注釋,包括對其功能、取值范圍、哪些函數(shù)或過程存取它以及存取時注意事項等的說明。示例:/*/*/*/*/*/*/*/*The ErrorCode when Stranslate */ 變量作用、含義Global Titlefailure, as follows1 GT Table error*/*/0 2 SUCSOthers no use */ 變量取值范圍GT erroronly function STr

15、anslate() in */this modual can modify it, and other module can visit it through call */the function GetGTTransErrorCode() */*/ 使用方法BYTE g_GTTranErrorCode;2-12:注釋與所描述內(nèi)容進(jìn)行同樣的縮排。說明:可使程序排版整齊,并方便注釋的閱讀與理解。示例:如下例子,排版不整齊,閱讀稍感不方便。void example_fun( void )/* code one comments */ CodeBlock One/* code two commen

16、ts */CodeBlock Two應(yīng)改為如下布局。void example_fun( void )/* code one comments */ CodeBlock One/* code two comments */CodeBlock Two2-13:將注釋與其上面的代碼用空行隔開。示例:如下例子,顯得代碼過于緊湊。/* code program/* codeprogramone comments code onetwo commentscode two*/*/應(yīng)如下書寫/* codeprogramone commentscode one*/* codeprogramtwo comment

17、scode two*/2-14:對變量的定義和分支語句(條件分支、循環(huán)語句等)必須編寫注釋。說明:這些語句往往是程序?qū)崿F(xiàn)某一特定功能的關(guān)鍵,對于來說,良好的注釋幫助更好的理解程序,有時甚至優(yōu)于看設(shè)計文檔。2-15:對于switch語句下的case語句,如果因為特殊情況需要處理完一個case后進(jìn)入下一個case處理,必須在該case語句處理完、下一個case語句前加上明確的注釋。說明:這樣比較清楚程序編寫者的意圖,有效防止無故遺漏 break 語句。示例(注意斜體加粗部分):case CMD_UP:Probreak;sUp();case CMD_DOWN:Probreak;sDown();cas

18、e CMD_FWD:ProsFwd();if (.).break;elseProsCFW_B();/nowjumpocaseCMD_Acase CMD_A:Probreak;sA();case CMD_B:Probreak;sB();case CMD_C:ProsC();break;case CMD_D:Probreak;sD();.2-1:避免在一行代碼或表達(dá)式的中間注釋。說明:除非必要,不應(yīng)在代碼或表達(dá)中間注釋,否則容易使代碼可理解性變差。2-2:通過對函數(shù)或過程、變量、結(jié)構(gòu)等正確自注釋的。名以及合理地組織代碼的結(jié)構(gòu),使代碼成為說明:清晰準(zhǔn)確的函數(shù)、變量等名,可增加代碼可讀性,并減少不必要

19、的注釋。2-3:在代碼的功能、意圖層次上進(jìn)行注釋,提供有用、額外的信息。說明:注釋的目的是解釋代碼的目的、功能和采用的方法,提供代碼以外的信息,幫助讀者理解代碼,防止沒必要的重復(fù)注釋信息。示例:如下注釋意義不大。/* if receive_flag is TRUE */ if (receive_flag)而如下的注釋則給出了額外有用的信息。/* if mtp receive a message from links */ if (receive_flag)2-4:在程序塊的結(jié)束行右方加注釋標(biāo)記,以表明某程序塊的結(jié)束。說明:當(dāng)代碼段較長,特別是多重嵌套時,這樣做可以使代碼更清晰,更便于閱讀。示例

20、:參見如下例子。if (.)/ program codewhile (index MAX_INDEX)/ program code /* end of while (index MAX_INDEX) */ / 指明該條 while 語句結(jié)束 /* end of if (.)*/ / 指明是哪條 if 語句結(jié)束2-5:注釋格式盡量,建議使用“/* */”。2-6:注釋應(yīng)考慮程序易讀及外觀排版的文,除非能用非常流利準(zhǔn)確的英文表達(dá)。,使用的語言若是中、英兼有的,建議多使用中說明:注釋語言不,影響程序易讀性和外觀排版,出于對的考慮,建議使用中文。3 標(biāo)識符命名3-1:標(biāo)識符名要清晰、明了,有明確含義,

21、同時使用完整的單詞或大家基本可以理解的縮寫,避免使人產(chǎn)生誤解。說明:較短的單詞可通過去掉“元音”形成縮寫;較長的單詞可取單詞的頭幾個字母形成縮寫;一些單詞有大家公認(rèn)的縮寫。示例:如下單詞的縮寫能夠被大家基本認(rèn)可。temp 可縮寫為 tmpflag 可縮寫為;s;inc ;sistic 可縮寫為increment 可縮寫為message 可縮寫為 msg ;3-2:命名中若使用特殊約定或縮寫,則要有注釋說明。說明:應(yīng)該在源文件的開始之處,對文件中所使用的縮寫或約定,特別是特殊的縮寫,進(jìn)行必要的注釋說明。3-3:自己特有說明:個人名風(fēng)格,要自始至終保持一致,不可來回變化。名風(fēng)格,在符合所在項目組或

22、產(chǎn)品組名規(guī)則的前提下,才可使用。(即命名規(guī)則中沒有規(guī)定到的地方才可有個人命名風(fēng)格)。3-4:對于變量命名,取單個字符(如i、j、k.),建議除了要有具體含義外,還能表明其變量類型、數(shù)據(jù)類型等,但i、j、k作局部循環(huán)變量是允許的。說明:變量,尤其是局部變量,如果用單個字符表示,很容易敲錯(如 i 寫成 j),而編譯時又檢查不出來,有可能為了這個小小的錯誤而花費(fèi)大量的查錯時間。示例:下面所示的局部變量名的定義方法可以借鑒。liv_Width其變量名解釋如下:l iv局部變量(Local) (其它:g全局變量(Global).)數(shù)據(jù)類型(erger)變量(Variable)(其它:c常量(Const

23、).)Width 變量含義這樣可以防止局部變量與全局變量重名。3-5:命名規(guī)范必須與所使用的系統(tǒng)風(fēng)格保持一致,并在同一項目中,比如采用UNIX的全小寫加下劃線的風(fēng)格或大小寫混排的方式,不要使用大小寫與下劃線混排的方式,用作特殊標(biāo)識如標(biāo)識成員變量或全局變量的m_和g_,其后加上大小寫混排的方式是允許的。示例: Add_User 不允許,add_user、AddUser、m_AddUser 允許。3-1:除非必要,不要用數(shù)字或較奇怪的字符來定義標(biāo)識符。示例:如下命名,使人產(chǎn)生疑惑。 #define _EXAMPLE_0_TEST_ #define _EXAMPLE_1_TEST_void set_

24、sls00( BYTE sls );應(yīng)改為有意義的單詞命名#define _EXAMPLE_UNIT_TEST_#define _EXAMPLE_ASSERT_TEST_ void set_udt_msg_sls( BYTE sls );3-2:在同一產(chǎn)品內(nèi),應(yīng)規(guī)劃好接口部分標(biāo)識符(變量、結(jié)構(gòu)、函數(shù)及常量)名,防止編譯、時產(chǎn)生。說明:對接口部分的標(biāo)識符應(yīng)該有更嚴(yán)格限制,防止。如可規(guī)定接口部分的變量與常量之前加上“模塊”標(biāo)識等。3-3:用正確的反義詞組命名具有互斥意義的變量或相作的函數(shù)等。說明:下面是一些在add / remove insert / delete中常用的反義詞組。begin/ e

25、nd/ lastcreate / destroy get / releaseput / get open / closestart / stopshow / hideincrement / decrementadd / delete min / maxnext / previous send / receive cut / paste示例:min_sum; max_sum;lockold / unlocknewsource /source / up / downdestinationadd_user( BYTE *user_name );delete_user( BYTE *user_name

26、 );3-4:除了編譯開關(guān)/頭文件等特殊應(yīng)用,應(yīng)避免使用_EXAMPLE_TEST_之類以下劃線開始和結(jié)尾的定義。4 可讀性4-1:注意運(yùn)算符的優(yōu)先級,并用括號明確表達(dá)式的操作順序,避免使用默認(rèn)優(yōu)先級。說明:防止閱讀程序時產(chǎn)生誤解,防止因默認(rèn)的優(yōu)先級與設(shè)計不符而導(dǎo)致程序出錯。示例:下列語句中的表達(dá)式word = if (aif (a(high 8) | low(1)(2)(3)| b)| b)& (a & c) (c & d)如果書寫為high 8 |lowa | b & a & c a | b c & d由于high 8 | low = ( higha | b & a & c = (a |

27、b) 8)& (a| low,& c),(1)(2)不會出錯,但語句不易理解;a | b c & d = a | (b c) &d,(3)造成了判斷條件出錯。4-2:避免使用不易理解的數(shù)字,用有意義的標(biāo)識來替代。涉及物理狀態(tài)或者含有物理意義的常量,不應(yīng)直接使用數(shù)字,必須用有意義的枚舉或宏來代替。示例:如下的程序可讀性差。if (Trunkindex.trunk_sTrunkindex.trunk_se = 0)e = 1;. / programcode應(yīng)改為如下形式。#define TRUNK_IDLE #define TRUNK_BUSY01if (Trunkindex.trunk_sTru

28、nkindex.trunk_se = TRUNK_IDLE)e = TRUNK_BUSY;. / program code4-1:源程序中關(guān)系較為緊密的代碼應(yīng)盡可能相鄰。說明:便于程序閱讀和查找。示例:以下代碼布局不太合理。 rect.length = 10; char_poi = str;rect.width = 5;若按如下形式書寫,可能更清晰一些。rect.length = 10;rect.width = 5; / 矩形的長與寬關(guān)系較密切,放在一起。char_poi = str;4-2:不要使用難懂的技巧性很高的語句,除非很有必要時。說技巧語句不等于高效率的程序,實際上程序的效率關(guān)鍵在于

29、算法。示例:如下表達(dá)式,考慮不周就可能出問題,也較難理解。* s_poi + += 1;* + s_poi += 1;應(yīng)分別改為如下。*ss_poi +=_poi+;1;/ 此二語句功能相當(dāng)于“ * s_poi + += 1; ”+*ss_poi;_poi +=1; / 此二語句功能相當(dāng)于“ * + s_poi += 1; ”5 變量、結(jié)構(gòu)5-1:去掉沒必要的公共變量。說明:公共變量是增大模塊間耦合的原因之一,故應(yīng)減少沒必要的公共變量以降低模塊間的耦合度。5-2:仔細(xì)定義并明確公共變量的含義、作用、取值范圍及公共變量間的關(guān)系。說明:在對變量的同時,應(yīng)對其含義、作用及取值范圍進(jìn)行注釋說明,同時若

30、有必要還應(yīng)說明與其它變量的關(guān)系。5-3:明確公共變量與操作此公共變量的函數(shù)或過程的關(guān)系,如、修改及創(chuàng)建等。說明:明確過程操作變量的關(guān)系后,將有利于程序的進(jìn)一步優(yōu)化、單元測試、系統(tǒng)聯(lián)調(diào)以及代碼等。這種關(guān)系的說明可在注釋或文檔中描述。示例:在源文件中,可按如下注釋形式說明。RELATIONStudent ScoreSystem_InitCreate CreateInput_RecModify ModifyPrAc Ac_RecSAc Ac_Score ss, Modifyss注:RELATION 為操作關(guān)系;System_Init、Input_Rec、Pr_Rec、S_Score為四個不同的函數(shù);

31、Student、Score 為兩個全局變量;Create 表示創(chuàng)建,Modify 表示修改,Acs 表示。其中,函數(shù) Input_Rec、S_Score 都可修改變量 Score,故此變量將引起函數(shù)間較大的耦合,并可能增加代碼測試、的難度。5-4:當(dāng)向公共變量傳遞數(shù)據(jù)時,要十分,防止賦與不合理的值或越界等現(xiàn)象發(fā)生。說明:對公共變量賦值時,若有必要應(yīng)進(jìn)行檢查,以提高代碼的可靠性、穩(wěn)定性。5-5:防止局部變量與公共變量同名。說明:若使用了較好名規(guī)則,那么此問題可自動消除。5-6:嚴(yán)禁使用初始化的變量作為右值。說明:特別是在 C/C+中賦值的指針,經(jīng)常會引起系統(tǒng)。5-1:構(gòu)造僅有一個模塊或函數(shù)可以修

32、改、創(chuàng)建,而其余有關(guān)模塊或函數(shù)只防止多個不同模塊或函數(shù)都可以修改、創(chuàng)建同一公共變量的現(xiàn)象。說明:降低公共變量耦合度。的公共變量,5-2:使用嚴(yán)格形式定義的、可移植的數(shù)據(jù)類型,盡量不要使用與具體硬件或切的變量。環(huán)境關(guān)系密說明:使用標(biāo)準(zhǔn)的數(shù)據(jù)類型,有利于程序的移植。示例:如下例子(在 DOS 下 BC3.1 環(huán)境中),在移植時可能產(chǎn)生問題。void main()registerindex; / 寄存器變量_AX = 0 x4000; / _AX 是 BC3.1 提供的寄存器“偽變量”. / program code5-3:結(jié)構(gòu)的功能要單一,是針對一種事務(wù)的抽象。說明:設(shè)計結(jié)構(gòu)時應(yīng)力爭使結(jié)構(gòu)代表一種

33、現(xiàn)實事務(wù)的抽象,而不是同時代表多種。結(jié)構(gòu)中的各元素應(yīng)代表同一事務(wù)的不同側(cè)面,而不應(yīng)把描述沒有關(guān)系或關(guān)系很弱的不同事務(wù)的元素放到同一結(jié)構(gòu)中。示例:如下結(jié)構(gòu)不太清晰、合理。typedef struct STUDENT_STRUunsigned unsignedunsignedchar charcharname8; /* students name */age;sex;/* students age */* students sex, as follows */* 0 - FEMALE; 1 - MALE */unsignedcharteacher_name8; /* the student tea

34、chers name */unisgned charteacher_sex; STUDENT;/* his teacher sex */若改為如下,可能更合理些。typedef struct TEACHER_STRUunsigned char name8; /* teacher name */unisgned char sex;/* teacher sex, as follows */* 0 - FEMALE; 1 - MALE */ TEACHER;typedef struct STUDENT_STRUunsigned unsignedunsignedchar charcharname8;

35、age;sex;/* students name */* students age */* students sex, as follows*/*0 - FEMALE; 1 -MALE */unsigned STUDENT;teacher_ind; /* his teacherindex*/5-4:不要設(shè)計面面俱到、非常靈活的數(shù)據(jù)結(jié)構(gòu)。說明:面面俱到、靈活的數(shù)據(jù)結(jié)構(gòu)反而容易引起誤解和操作。5-5:不同結(jié)構(gòu)間的關(guān)系不要過于復(fù)雜。說明:若兩個結(jié)構(gòu)間關(guān)系較復(fù)雜、密切,那么應(yīng)合為一個結(jié)構(gòu)。示例:如下兩個結(jié)構(gòu)的構(gòu)造不合理。typedef struct_ONE_STRUunsigned unsigned

36、unsignedunsignedchar char charcharname8;addr40; sex;city15;_ONE;typedef struct_TWO_STRUunsignedunsigned unsignedcharchar charname8; age;_TWO;由于兩個結(jié)構(gòu)都是描述同一事物的,那么不如一個結(jié)構(gòu)。typedef struct_STRUunsigned unsigned unsigned unsigned unsigned unsigned;char char char char charcharname8; age; sex;addr40;city15;5-6

37、:結(jié)構(gòu)中元素的個數(shù)應(yīng)適中。若結(jié)構(gòu)中元素個數(shù)過多可考慮依據(jù)某種原則把元素組成不同的子結(jié)構(gòu),以減少原結(jié)構(gòu)中元素的個數(shù)。說明:增加結(jié)構(gòu)的可理解性、可操作性和可性。示例:假如認(rèn)為如上的_ typedef struct結(jié)構(gòu)元素過多,那么可如下對之劃分。_BASE_INFO_STRUunsigned unsignedunsignedchar charcharname8; age;sex;_BASE_INFO;typedef struct_ADDRESS_STRUunsigned unsignedunsignedchar charcharaddr40;city15;_ADDRESS;typedefstruc

38、t_STRU_BASE_INFO_ADDRESS_base;_addr;5-7:仔細(xì)設(shè)計結(jié)構(gòu)中元素的布局與排列順序,使結(jié)構(gòu)容易理解、節(jié)省占用空間,并減少引起誤用現(xiàn)象。說明:合理排列結(jié)構(gòu)中元素順序,可節(jié)省空間并增加可理解性。示例:如下結(jié)構(gòu)中的位域排列,將占較大空間,可讀性也稍差。typedef structunsignedEXAMPLE_STRUvalid: 1;unsigned EXAMPLE;set_: 1;若改成如下形式,不僅可節(jié)省 1 字節(jié)空間,可讀性也變好了。typedef structunsigned unsignedEXAMPLE_STRUvalid: 1;set_;: 1; EX

39、AMPLE;5-8:結(jié)構(gòu)的設(shè)計要盡量考慮向前兼容和以后的版本升級,并為某些未來可能的應(yīng)用保留余地(如預(yù)留一些空間等)。說明:向前兼容的特性,是產(chǎn)品是否成功的重要標(biāo)志之一。如果要想使產(chǎn)品具有較好的前向兼容,那么在產(chǎn)品設(shè)計之初就應(yīng)為以后版本升級保留一定余地,并且在產(chǎn)品升級時必須考慮前一版本的各種特性。5-9:留心具體語言及編譯器處理不同數(shù)據(jù)類型的原則及有關(guān)細(xì)節(jié)。說明:如在 C 語言中,sic 局部變量將在內(nèi)存“數(shù)據(jù)區(qū)”中生成,而非 sic 局部變量將在“堆?!敝猩?。這些細(xì)節(jié)對程序質(zhì)量的保證非常重要。5-10:編程時,要注意數(shù)據(jù)類型的強(qiáng)制轉(zhuǎn)換。說明:當(dāng)進(jìn)行數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)換時,其數(shù)據(jù)的意義、轉(zhuǎn)換后的

40、取值等都有可能發(fā)生變化,而這些細(xì)節(jié)若考慮不周,就很有可能留下隱患。5-11:對編譯系統(tǒng)默認(rèn)的數(shù)據(jù)類型轉(zhuǎn)換,也要有充分的認(rèn)識。示例:如下賦值,多數(shù)編譯器不產(chǎn)生告警,但值的含義還是稍有變化。char chr;unsigned shortexam;chr = -1;exam = chr; / 編譯器不產(chǎn)生告警,此時 exam 為 0 xF。5-12:盡量減少沒有必要的數(shù)據(jù)類型默認(rèn)轉(zhuǎn)換與強(qiáng)制轉(zhuǎn)換。5-13:合理地設(shè)計數(shù)據(jù)并使用自定義數(shù)據(jù)類型,避免數(shù)據(jù)間進(jìn)行不必要的類型轉(zhuǎn)換。5-14:對自定義數(shù)據(jù)類型進(jìn)行恰當(dāng)命名,使它成為自描述性的,以提高代碼可讀性。注意其命名方式在同一產(chǎn)品中的。說明:使用自定義類型,

41、可以彌補(bǔ)編程語言提供類型少、信息量不足的缺點,并能使程序清晰、簡潔。示例:可參考如下方式自定義數(shù)據(jù)類型。下面的 typedef typedeftypedef可使數(shù)據(jù)類型的使用簡潔、明了。unsignedunsigned unsignedchar BYTE; short WORD;DWORD;下面的typedef typedef可使數(shù)據(jù)類型具有更豐富的含義。float DISTANCE; float SCORE;5-15:當(dāng)用于分布式環(huán)境或不同CPU間通信環(huán)境的數(shù)據(jù)結(jié)構(gòu)時,必須考慮機(jī)器的字節(jié)順序、使用的位域及字節(jié)對齊等問題 。說明:比如el CPU 與 68360 CPU,在處理位域及整數(shù)時,其

42、在內(nèi)存存放的“順序”正好相反。示例:假如下短整數(shù)及結(jié)構(gòu)。unsigned short typedef structunsigned unsignedunsignedexam;EXAM_BIT_STRU/* 1;1;1;el 68360*/765A1:A2:A3:/*/*/*bit bitbit012*/*/*/ EXAM_BIT;如下是el CPU 生成短整數(shù)及位域的方式。內(nèi)存: 012. (從低到高,以字節(jié)為)exam exam 低字節(jié) exam 高字節(jié)內(nèi)存:EXAM_BIT0 bitA11 bitA22 bitA3. (字節(jié)的各“位”)如下是 68360內(nèi)存: 0CPU 生成短整數(shù)及位域的

43、方式。12. (從低到高,以字節(jié)為)exam exam 高字節(jié) exam 低字節(jié)內(nèi)存:EXAM_BIT7 bitA16 bitA25 bitA3. (字節(jié)的各“位”)說明:在對齊方式下,CPU 的運(yùn)行效率要快得多。示例:如下圖,當(dāng)一個 long 型數(shù)(如圖中 long1)在內(nèi)存中的位置正好與內(nèi)存的字邊界對齊時,CPU 存取這個數(shù)只需一次內(nèi)存,而當(dāng)一個 long 型數(shù)(如圖中的 long2)在內(nèi)存中的位置了字邊界時,CPU 存取這個數(shù)就需要多次內(nèi)存,如 i960cx這樣的數(shù)需讀內(nèi)存三次(一個 BYTE、一個 SHORT、一個 BYTE,由 CPU 的微代碼執(zhí)行,對透明),所有對齊方式下 CPU

44、的運(yùn)行效率明顯快多了。18162432|long1 |long1|long1 | long1 | long2 |long2 |long2|long2 |.6 函數(shù)、過程6-1:對所調(diào)用函數(shù)的錯誤返回碼要仔細(xì)、全面地處理。6-2:明確函數(shù)功能,精確(而不是近似)地實現(xiàn)函數(shù)設(shè)計。6-3:編寫可重入函數(shù)時,應(yīng)注意局部變量的使用(如編寫C/C+語言的可重入函數(shù)時,應(yīng)使用auto即缺省態(tài)局部變量或寄存器變量)。說明:編寫 C/C+語言的可重入函數(shù)時,不應(yīng)使用 s處理,才能使函數(shù)具有可重入性。ic 局部變量,否則必須經(jīng)過特殊6-4:編寫可重入函數(shù)時,若使用全局變量,則應(yīng)通過關(guān)中斷、信號量(即P、V操作)等

45、對其加以保護(hù)。說明:若對所使用的全局變量不加以保護(hù),則此函數(shù)就不具有可重入性,即當(dāng)多個進(jìn)程調(diào)用此函數(shù)時,很有可能使有關(guān)全局變量變?yōu)椴豢芍獱顟B(tài)。示例:假設(shè) Exam 是函數(shù)不具有可重入性。型全局變量,函數(shù) Squre_Exam 返回 Exam 平方值。那么如下unsignedunsignedexample(para )temp;Exam =temp =para; / (*)Square_Exam( );returntemp;此函數(shù)若被多個進(jìn)程調(diào)用的話,其結(jié)果可能是未知的,因為當(dāng)(*)語句剛執(zhí)行完后,另外一個使用本函數(shù)的進(jìn)程可能正好被激活,那么當(dāng)新激活的進(jìn)程執(zhí)行到此函數(shù)時,將使Exam 賦與另一個

46、不同的 para 值,所以當(dāng)控制重新回到“temp = Square_Exam( )”后,計算出的 temp 很可能不是預(yù)想中的結(jié)果。此函數(shù)應(yīng)如下改進(jìn)。unsignedunsignedexample(para )temp;申請信號量操作 Exam = para;temp = Square_Exam(/ 若申請不到“信號量”,說明另外的進(jìn)程正處于/ 給 Exam 賦值并計算其平方過程中(即正在使用此); / 信號),本進(jìn)程必須等待其信號后,才可繼信號量操作/ 續(xù)執(zhí)行。若申請到信號,則可繼續(xù)執(zhí)行,但其/ 它進(jìn)程必須等待本進(jìn)程/ 用本信號。信號量后,才能再使return temp;6-5:在同一項目

47、組應(yīng)明確規(guī)定對接口函數(shù)參數(shù)的口函數(shù)本身負(fù)責(zé),缺省是由函數(shù)調(diào)用者負(fù)責(zé)。檢查應(yīng)由函數(shù)的調(diào)用者負(fù)責(zé)還是由接說明:對于模塊間接口函數(shù)的參數(shù)的檢查這一問題,往往有兩個現(xiàn)象,即:要么是調(diào)用者和被調(diào)用者對參數(shù)均不作檢查,結(jié)果就遺漏了檢查這一必要的處理過程,造成問題隱患;要么就是調(diào)用者和被調(diào)用者均對參數(shù)進(jìn)行檢查,這種情況雖不會造成問題,但產(chǎn)生了冗余代碼,降低了效率。6-1:防止將函數(shù)的參數(shù)作為工作變量。說明:將函數(shù)的參數(shù)作為工作變量,有可能錯誤地改變參數(shù)內(nèi)容,所以很。對必須改變的參數(shù),最好先用局部變量,最后再將該局部變量的內(nèi)容賦給該參數(shù)。示例:下函數(shù)的實現(xiàn)不太好。void sum_data( unsigned

48、num,*data,*sum )unsignedcount;*sum = 0;for (count = 0; count num; count+)*sum += dount; / sum 成了工作變量,不太好。若改為如下,則更好些。void sum_data( unsignednum,*data,*sum )unsignedcount ;sum_temp;sum_temp = 0;for (count = 0; count b ) ? a : b ;改為如下就很清晰了。max (a,b)return (a b) ? a : b);value = max(a,b);或改為如下。#define M

49、AX(a,b) (a) (b) ? (a) : (b)value = MAX(a,b);6-5:不要設(shè)計多用途面面俱到的函數(shù)。說明:多功能集于一身的函數(shù),很可能使函數(shù)的理解、測試、等變得。6-6:函數(shù)的功能應(yīng)該是可以的,也就是只要輸入數(shù)據(jù)相同就應(yīng)產(chǎn)生同樣的輸出。說明:帶有內(nèi)部“器”的函數(shù)的功能可能是不可的,因為它的輸出可能取決于內(nèi)部器(如某標(biāo)記)的狀態(tài)。這樣的函數(shù)既不易于理解又不利于測試和。在 C/C+語言中,函數(shù)的 sic 局部變量是函數(shù)的內(nèi)部器,有可能使函數(shù)的功能不可,然而,當(dāng)某函數(shù)的返回值為指針類型時,則必須是 S若為 AUTO 類,則返回為錯針。IC 的局部變量的地址作為返回值,示例:

50、如下函數(shù),其返回值(即功能)是不可的。unsignedunsignedeger_sum( unsignedbase )index;sum = 0; / 注意,是 sic 類型的。sic unsigned/ 若改為 auto 類型,則函數(shù)即變?yōu)榭蒮or (index = 1; index B-C-A),影響程序的可理解性;遞歸調(diào)用一般都占用較多的系統(tǒng)資源(如棧空間);遞歸調(diào)用對程序的測試有一定影響。故除非為某些算法或功能的實現(xiàn)方便,應(yīng)減少沒必要的遞歸調(diào)用。6-25:仔細(xì)分析模塊的功能及性能需求,并進(jìn)一步細(xì)分,同時若有必要畫出有關(guān)數(shù)據(jù)流圖,據(jù)此來進(jìn)行模塊的函數(shù)劃分與組織。說明:函數(shù)的劃分與組織是模

51、塊的實現(xiàn)過程中很關(guān)鍵的步驟,如何劃分出合理的函數(shù)結(jié)構(gòu),關(guān)系到模塊的最終效率和可性、可測性等。根據(jù)模塊的功能圖或/及數(shù)據(jù)流圖出函數(shù)結(jié)構(gòu)是常用方法之一。6-26:改進(jìn)模塊中函數(shù)的結(jié)構(gòu),降低函數(shù)間的耦合度,并提高函數(shù)的獨(dú)立性以及代碼可讀性、效率和可性。優(yōu)化函數(shù)結(jié)構(gòu)時,要遵守以下原則:不能影響模塊功能的實現(xiàn)。仔細(xì)考查模塊或函數(shù)出錯處理及模塊的性能要求并進(jìn)行完善。(3)通過分解或合并函數(shù)來改進(jìn)結(jié)構(gòu)。考查函數(shù)的規(guī)模,過大的要進(jìn)行分解。降低函數(shù)間接口的復(fù)雜度。不同層次的函數(shù)調(diào)用要有較合理的扇入、扇出。(7)函數(shù)功能應(yīng)可。(8)提高函數(shù)內(nèi)聚。(單能的函數(shù)內(nèi)聚最高)說明:對初步劃分后的函數(shù)結(jié)構(gòu)應(yīng)進(jìn)行改進(jìn)、優(yōu)化,

52、使之更為合理。6-27:在多任務(wù)操作系統(tǒng)的環(huán)境下編程,要注意函數(shù)可重入性的構(gòu)造。說明:可重入性是指函數(shù)可以被多個任務(wù)進(jìn)程調(diào)用。在多任務(wù)操作系統(tǒng)中,函數(shù)是否具有可重入性是非常重要的,因為這是多個進(jìn)程可以共用此函數(shù)的必要條件。另外,編譯器是否提供可重入函數(shù)庫,與它所服務(wù)的操作系統(tǒng)有關(guān),只有操作系統(tǒng)是多任務(wù)時,編譯器才有可能提供可重入函數(shù)庫。如 DOS 下 BC 和 MSC 等就不具備可重入函數(shù)庫,因為 DOS 是單用戶單任務(wù)操作系統(tǒng)。6-28:避免使用BOOL參數(shù)。說明:原因有二,其一是 BOOL 參數(shù)值無意義,TURE/FALSE 的含義是非常模糊的,在調(diào)用時很難知道該參數(shù)到底傳達(dá)的是什么意思;

53、其二是 BOOL 參數(shù)值不利于擴(kuò)充。還有 NULL也是一個無意義的單詞。6-29: 對于提供了返回值的函數(shù),在時最好使用其返回值。6-30:當(dāng)一個過程(函數(shù))中對較長變量(一般是結(jié)構(gòu)的成員)有較多意義相當(dāng)?shù)暮甏妗Uf明:這樣可以增加編程效率和程序的可讀性。時,可以用一個示例:在某過程中較多TheReceiveBufferSocket.byDataPtr,則可以通過以下宏定義來代替:# define pSOCKDAheReceiveBufferScoket.byDataPtr7 可測性7-1:在同一項目組或產(chǎn)品組內(nèi),要有一套的為集成測試與系統(tǒng)聯(lián)調(diào)準(zhǔn)備的調(diào)測開關(guān)及相應(yīng)打印函數(shù),并且要有詳細(xì)的說明。

54、說明:本規(guī)則是針對項目組或產(chǎn)品組的。7-2:在同一項目組或產(chǎn)品組內(nèi),調(diào)測打印出的信息串的格式要有要有所在模塊名(或源文件名)及行號。的形式。信息串中至少說明:的調(diào)測信息格式便于集成測試。7-3:編程的同時要為單元測試選擇恰當(dāng)?shù)臏y試點,并仔細(xì)構(gòu)造測試代碼、測試用例,同時給出明確的注釋說明。測試代碼部分應(yīng)作為(模塊中的)一個子模塊,以方便測試代碼在模塊中的安裝與拆卸(通過調(diào)測開關(guān))。說明:為單元測試而準(zhǔn)備。7-4:在進(jìn)行集成測試/系統(tǒng)聯(lián)調(diào)之前,要構(gòu)造好測試環(huán)境、測試項目及測試用例,同時仔細(xì)分析并優(yōu)化測試用例,以提高測試效率。說明:好的測試用例應(yīng)盡可能模擬出程序所遇到的邊界值、各種復(fù)雜環(huán)境及一些情況

55、等。7-5:使用斷言來發(fā)現(xiàn)問題,提高代碼可測性。說明:斷言是對某種假設(shè)條件進(jìn)行檢查(可理解為若條件成立則無動作,否則應(yīng)),它可以快速發(fā)現(xiàn)并定位問題,同時對系統(tǒng)錯誤進(jìn)行自動。斷言可以對在系統(tǒng)中隱藏很深,用其它極難發(fā)現(xiàn)的問題進(jìn)行定位,從而縮短問題定位時間,提高系統(tǒng)的可測性。實際應(yīng)用時,可根據(jù)具體情況靈活地設(shè)計斷言。示例:下面是 C 語言中的一個斷言,來設(shè)計的。(其中 NULL 為 0L)#ifdef _EXAM_ASSERT_TEST_ / 若使用斷言測試void exam_assert( char * file_name, unsignedline_no )prf( nEXAMAssert fa

56、iled: %s, line %un,file_name, line_no );abort( );#define EXAM_ASSERT( condition )if (condition) / 若條件成立,則無動作NULL;else / 否則exam_assert( _FILE , LINE_ )#else / 若不使用斷言測試#define EXAM_ASSERT(condition) NULL#endif /* end of ASSERT */7-6:用斷言來檢查程序正常運(yùn)行時不應(yīng)發(fā)生但在調(diào)測時有可能發(fā)生的情況。7-7:不能用斷言來檢查最終產(chǎn)品肯定會出現(xiàn)且必須處理的錯誤情況。說明:斷言是

57、用來處理不應(yīng)該發(fā)生的錯誤情況的,對于可能會發(fā)生的且必須處理的情況要寫防錯程序,而不是斷言。如某模塊收到其它模塊或鏈的消息后,要對消息的合理性進(jìn)行檢查,此過程為正常的錯誤檢查,不能用斷言來實現(xiàn)。7-8:對較復(fù)雜的斷言加上明確的注釋。說明:為復(fù)雜的斷言加注釋,可澄清斷言含義并減少不必要的誤用。7-9:用斷言確認(rèn)函數(shù)的參數(shù)。示例:假設(shè)某函數(shù)參數(shù)中有一個指針,那么使用指針前可對它檢查,如下。exam_fun( unsigned char *str )EXAM_ASSERT( str != NULL ); / 用斷言檢查“假設(shè)指針不為空”這個條件. /othrogram code7-10:用斷言保證沒有

58、定義的特性或功能不被使用。示例:假設(shè)某通信模塊在設(shè)計時,準(zhǔn)備提供“無連接”和“連接” 這兩種業(yè)務(wù)。但當(dāng)前的版本中僅實現(xiàn)了“無連接”業(yè)務(wù),且在此版本的正式版中,用戶(上層模塊)不應(yīng)產(chǎn)生“連接”業(yè)務(wù)的請求,那么在測試時可用斷言檢查用戶是否使用“連接”業(yè)務(wù)。如下。#define EXAM_CONNECTIONLESS 0 / 無連接業(yè)務(wù)1 / 連接業(yè)務(wù)#define EXAM_CONNECTIONmsg_pros( EXAM_MESSAGE *msg )unsigned char service; /* message service class */EXAM_ASSERT( msg != NULL

59、 );service = get_msg_service_class( msg );EXAM_ASSERT( service != EXAM_CONNECTION ); / 假設(shè)不使用連接業(yè)務(wù). /othrogram code7-11:用斷言對程序開發(fā)環(huán)境(piler/Hardware)的假設(shè)進(jìn)行檢查。說明:程序運(yùn)行時所需的軟硬件環(huán)境及配置要求,不能用斷言來檢查,而必須由一段專門代碼處理。用斷言僅可對程序開發(fā)環(huán)境中的假設(shè)及所配置的某版本軟硬件是否具有某種功能的假設(shè)進(jìn)行檢查。如某網(wǎng)卡是否在系統(tǒng)運(yùn)行環(huán)境中配置了,應(yīng)由程序中正式代碼來檢查;而此網(wǎng)卡是否具有某設(shè)想的功能,則可由斷言來檢查。對編譯器提供

60、的功能及特性假設(shè)可用斷言檢查,原因是最終產(chǎn)品(即運(yùn)行代碼或機(jī)器碼)與編譯器已沒有任何直接關(guān)系,即運(yùn)行過程中(注意不是編譯過程中)不會也不應(yīng)該對編譯器的功能提出任何需求。示例:用斷言檢查編譯器的EXAM_ASSERT( sizeof(型數(shù)據(jù)占用的內(nèi)存空間是否為 2,如下。) = 2 );7-12:正式說明:加快產(chǎn)品中應(yīng)把斷言及其它調(diào)測代碼去掉(即把有關(guān)的調(diào)測開關(guān)關(guān)掉)。運(yùn)行速度。7-13:在系統(tǒng)中設(shè)置與取消有關(guān)測試,不能對實現(xiàn)的功能等產(chǎn)生影響。說明:即有測試代碼的關(guān)掉測試代碼的,在功能行為上應(yīng)一致。7-14:用調(diào)測開關(guān)來切換的不同源文件,以減少的DEBUG版和正式版,而不要同時存在正式版本和DE

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論