![DSP C語言編程規(guī)范_第1頁](http://file4.renrendoc.com/view/a91a47b27de944331a5d346b82fa116f/a91a47b27de944331a5d346b82fa116f1.gif)
![DSP C語言編程規(guī)范_第2頁](http://file4.renrendoc.com/view/a91a47b27de944331a5d346b82fa116f/a91a47b27de944331a5d346b82fa116f2.gif)
![DSP C語言編程規(guī)范_第3頁](http://file4.renrendoc.com/view/a91a47b27de944331a5d346b82fa116f/a91a47b27de944331a5d346b82fa116f3.gif)
![DSP C語言編程規(guī)范_第4頁](http://file4.renrendoc.com/view/a91a47b27de944331a5d346b82fa116f/a91a47b27de944331a5d346b82fa116f4.gif)
![DSP C語言編程規(guī)范_第5頁](http://file4.renrendoc.com/view/a91a47b27de944331a5d346b82fa116f/a91a47b27de944331a5d346b82fa116f5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、DSPC語言編程規(guī)范版本時間作者備注Version1.02010.02.24劉昊創(chuàng)建編寫目的:此規(guī)范主要用于規(guī)范基于DSP的代碼開發(fā),可以有效提高代碼的可讀性、可移植性、可靠性等,提高DSP的開發(fā)效率,其它的C或C+開發(fā)也可以參考此規(guī)范,此規(guī)范對C或C+編程有普遍指導(dǎo)性。其中第19為基礎(chǔ)篇,第1014為提高篇。TOC o 1-5 h z HYPERLINK l bookmark2 1.目錄結(jié)構(gòu)2 HYPERLINK l bookmark4 各文件的功能劃分2 HYPERLINK l bookmark12 排版4 HYPERLINK l bookmark30 4.注釋11 HYPERLINK l
2、 bookmark80 標(biāo)識符命名15 HYPERLINK l bookmark106 宏18 HYPERLINK l bookmark108 可讀性19 HYPERLINK l bookmark116 變量、結(jié)構(gòu)21 HYPERLINK l bookmark152 函數(shù)、過程26 HYPERLINK l bookmark204 可測性33 HYPERLINK l bookmark236 程序效率38 HYPERLINK l bookmark272 質(zhì)量保證42 HYPERLINK l bookmark312 代碼編輯、編譯、審查50 HYPERLINK l bookmark320 代碼測試、
3、維護(hù)511.目錄結(jié)構(gòu)如下圖所示,一個工程的根目錄應(yīng)該新建三個文件夾:src、include、lib,src文件夾用來存放*.c文件(C語言)、*.cpp文件(C+語言)、*.asm文件(匯編);include文件夾用來存放*.h文件、*.inc文件、*.dat文件;lib文件夾用來存放*.lib及其相關(guān)的文件。與工程相關(guān)的文件放在工程的根目錄下,如.pjt(工程文件)、.cmd、.cdb等。一Debug_jinclude|目srccc_bui1d_Hebug.log薊Debug,lkfSfftl6xl6t.pa2畫p_itSfftl6xl6t.sbl茍nk.cmd2.各文件的功能劃分src文件
4、夾里的*.c文件(C語言)、*.cpp文件(C+語言)、*.asm文件(匯編)用來做每個函數(shù)的具體實現(xiàn),一個完整功能實現(xiàn)相關(guān)的函數(shù)放在一個文件中實現(xiàn)。每個*.c文件(C語言)、*.cpp文件(C+語言)都要有一個同名的*.h文件,在這個.h文件中寫每個函數(shù)的聲明,例如foo.c文件應(yīng)該有一個foo.h文件包含foo.c中每個函數(shù)的聲明,且每個頭文件都應(yīng)該用內(nèi)部保護(hù)符保護(hù)每個頭文件,以避免在多次包含時重新定義:例如,頭文件foo.h應(yīng)該采用下面的一般形式:#ifndef_FOO_H#define_FOO_H/文件內(nèi)容#include“MACRO.h”#include“TYPE.h”#includ
5、e“*.h”externintfuna(inta,intb,intc);#endif其中,有幾個特殊的頭文件用來做一些整個工程的宏定義或是類型定義,如XXX_DSP_MACRO.h用來定義整個工程所有的宏定義,XXX_DSP_TYPE.h用來定義整個工程所有的類型定義。*.inc文件用來定義全局變量,XXX_DSP_GBL_L2.inc文件用來定義分配在DSP的L2里全局變量,XXX_DSP_GBL_SDRAM.inc文件用來定義分配在DSP的SDRAM里全局變量,其具體寫如例:#includeXXX_DSP_MACRO.h#includeXXX_DSP_TYPE.h#ifdef_GBL_EX
6、#defineGBL_extern#else#defineGBL_externextern#endif/*FFT旋轉(zhuǎn)因子*/#ifdef_GBL_EX#pragmaDATA_ALIGN(gacsfftFactor,16)#endifGBL_externconstINT32gacsfftFactor128#ifdef_GBL_EX=#includeFFT128.dat#endif3.排版3.1:程序塊要采用縮進(jìn)風(fēng)格編寫,縮進(jìn)的空格數(shù)為4個,對齊只能使用空格鍵,不使用TAB鍵。說明:對于由開發(fā)工具自動生成的代碼可以有不一致(不做強(qiáng)制要求)3.2:相對獨立的程序塊之間、變量說明之后必須加空行。示例:
7、如下例子不符合規(guī)范。if(!valid_ni(ni)./programcoderepssn_ind=ssn_dataindex.repssn_index;repssn_ni=ssn_dataindex.ni;應(yīng)如下書寫:if(!valid_ni(ni)./programcoderepssn_ind=ssn_dataindex.repssn_index;repssn_ni=ssn_dataindex.ni;3.3:較長的語句(80字符)要分成多行書寫,長表達(dá)式要在低優(yōu)先級操作符處劃分新行,操作符放在新行之首,劃分出的新行要進(jìn)行適當(dāng)?shù)目s進(jìn),使排版整齊,語句可讀。示例:perm_count_msg.
8、head.len=NO7_TO_STAT_PERM_COUNT_LEN+STAT_SIZE_PER_FRAM*sizeof(_UL);act_task_tableframe_id*STAT_TASK_CHECK_NUMBER+index.occupied=stat_poiindex.occupied;3.4:循環(huán)、判斷等語句中若有較長的表達(dá)式或語句,則要進(jìn)行適應(yīng)的劃分,長表達(dá)式要在低優(yōu)先級操作符處劃分新行,操作符放在新行之首。示例:if(tasknomax_act_task_number)&(n7stat_stat_item_valid(stat_item)./programcodefor(i
9、=0,j=0;(iBufferKeywordword_index.word_length)&(jNewKeyword.word_length);i+,j+)./programcodefor(i=0,j=0;(ifirst_word_length)&(j),后不應(yīng)加空格。說明:采用這種松散方式編寫代碼的目的是使代碼更加清晰。由于留空格所產(chǎn)生的清晰性是相對的,所以,在已經(jīng)非常清晰的語句中沒有必要再留空格,如果語句已足夠清晰則括號內(nèi)側(cè)(即左括號后面和右括號前面)不需要加空格,多重括號間不必加空格,因為在C/C+語言中括號已經(jīng)是最清晰的標(biāo)志了。在長語句中,如果需要加的空格非常多,那么應(yīng)該保持整體清晰,
10、而在局部不加空格。給操作符留空格時不要連續(xù)留兩個以上空格。示例:(1)逗號、分號只在后面加空格。inta,b,c;(2)比較操作符,賦值操作符=、+=,算術(shù)操作符+、%,邏輯操作符&,位域操作符VV、A等雙目操作符的前后加空格。if(current_time=MAX_TIME_VALUE)a=b+c;a*=2;a=bA2;!、+、-、&(地址運算符)等單目操作符前后不加空格。*p=a;/*內(nèi)容操作*與內(nèi)容之間*/flag=!isEmpty;/*非操作!與內(nèi)容之間*/p=&mem;/*地址操作&與內(nèi)容之間*/i+;/*+,-與內(nèi)容之間*/-、.前后不加空格。p-id=pid;/*-指針前后不加空
11、格*/if、for、while、switch等與后面的括號間應(yīng)加空格,使if等關(guān)鍵字更為突出、明顯。if(a=b&cd)3.9:if、else、for、switch的標(biāo)準(zhǔn)寫法:if(條件語句)/programcodeelse/programcodefor(i=0;iK,t*k1*k1*/JSvt*k1*k1*、1*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*k1*k1*/rT*rT*/*DSP_cmpy16x16兩組復(fù)數(shù)進(jìn)行點乘小端對齊模式*/*DSP_cmpy_col16x16一個復(fù)數(shù)與一組復(fù)數(shù)點乘小端對齊模式*/*DSP_cmpy16x16_32兩組
12、復(fù)數(shù)進(jìn)行點乘小端對齊模式*/*DSP_conj_cmpy16x16_32兩組復(fù)數(shù)進(jìn)行共軛點乘小端對齊模式*/*DSP_matrix_cmpy16x16矩陣復(fù)乘小端對齊模式*/*DSP_conv16x16卷積運算小端對齊模式*/*DSP_matrix_H16x16矩陣求共軛轉(zhuǎn)置小端對齊模式*/*DSP_chol16x16矩陣cholesky分解小端對齊模式*/*DSP_matrix_X_InvUX矩陣除以U矩陣,U為上三角小端對齊模式*/*DSP_matrix_X11_F11X-F*FH小端對齊模式*/*DSP_16x16to32x3216x16的復(fù)數(shù)擴(kuò)展為32x32小端對齊模式*/*DSP_3
13、2x32to16x1632x32的復(fù)數(shù)壓縮為16x16小端對齊模式*/fK,t*k1*k1*k1*k1*k1*k1*k1*k1*k1*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、!K,t*k1*k1*/JS*1*1*1*x*、t*、t*、t*、t*、t*、t*、t*、t*、t*1*
14、1*1*1*1*/rT*rT*rT*TxrT*rT*/4.3:函數(shù)頭部應(yīng)進(jìn)行注釋,列出:函數(shù)的目的/功能、輸入?yún)?shù)、輸出參數(shù)、返回值等示例:下面這段函數(shù)的注釋比較標(biāo)準(zhǔn),當(dāng)然,并不局限于此格式,但上述信息建議要包含在內(nèi)。7*1*1*1*1*1*1*1*1*1*1*1*1*1*1*vt*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*/rTrT*Function:/函數(shù)名稱Description:/函數(shù)功能、性能等的描述Input:/輸入?yún)?shù)說明,包括每個參數(shù)的作/用、取值說明及參數(shù)間關(guān)系。
15、Output:/對輸出參數(shù)的說明。Return:/函數(shù)返回值的說明Others:/其它說明*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*1*k1*、t*、t*、t*、t*、t*、t*、t*、!*1*1*1*1*1*1*1*1*1*1*、t*、t*、t*、t*、t*、t*、t*1*1*1*1*/rTrT/fK,t*k1*k1*k1*k1*k1*k1*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*
16、、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*K,t*/rT*rT*JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSrT*rT*/*函數(shù)名稱:DSP_cmpy16x16()*/*函數(shù)功能:小端對齊模式下進(jìn)行復(fù)數(shù)乘法*/*輸入輸出復(fù)數(shù)均為16x16的復(fù)數(shù)*/*輸入:psrc1乘數(shù)1的數(shù)組指針*/*psrc2乘數(shù)2的數(shù)組指針*/*lenth數(shù)組的長度*/*qs輸出結(jié)果需要進(jìn)行的移位值*/*輸入:pdst輸
17、出的數(shù)組指針*/*返回值:無*/fK,t*k1*vt*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*、t*K,t*k1*/JSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSJSrT*rT*/4.4:邊
18、寫代碼邊注釋,修改代碼同時修改相應(yīng)的注釋,以保證注釋與代碼的一致性。不再有用的注釋要刪除。注釋應(yīng)與其描述的代碼相近,對代碼的注釋應(yīng)放在其上方或右方(對單條語句的注釋)相鄰位置,不可放在下面,如放于上方則需與其上面的代碼用空行隔開。注釋的內(nèi)容要清楚、明了,含義準(zhǔn)確,防止注釋二義性。說明:錯誤的注釋不但無益反而有害。4.5:對于所有有物理含義的變量、常量,如果其命名不是充分自注釋的,在聲明時都必須加以注釋,說明其物理含義。變量、常量、宏的注釋應(yīng)放在其上方相鄰位置或右方。示例:/*activestatistictasknumber*/#defineMAX_ACT_TASK_NUMBER10004.6
19、:數(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)。/*sccpinterfacewithsccpuserprimitivemessagename*/enumSCCP_USER_PRIMITIVEN_UNITDATA_IND,/*sccpnotifysccpuserunitdatacome*/N_NOTICE_IND,/*sccpnotifyusertheNo.7networkcannot*/*transmissionthis
20、message*/N_UNITDATA_REQ,/*sccpusersunitdatatransmissionrequest*/;4.7:全局變量要有較詳細(xì)的注釋,包括對其功能、取值范圍、哪些函數(shù)或過程存取它以及存取時注意事項等的說明。示例:/*TheErrorCodewhenSCCPtranslate*/*GlobalTitlefailure,asfollows*/變量作用、含義/*0SUCCESS1GTTableerror*/*2GTerrorOthersnouse*/變量取值范圍BYTEg_GTTranErrorCode;4.8:將注釋與其上面的代碼用空行隔開,不允許在一行代碼或表達(dá)式的
21、中間插入注釋示例:如下例子,顯得代碼過于緊湊。/*codeonecomments*/programcodeone/*codetwocomments*/programcodetwo應(yīng)如下書寫/*codeonecomments*/programcodeone/*codetwocomments*/programcodetwo4.9:對變量的定義和分支語句(條件分支、循環(huán)語句等)必須編寫注釋。說明:這些語句往往是程序?qū)崿F(xiàn)某一特定功能的關(guān)鍵,對于維護(hù)人員來說,良好的注釋幫助更好的理解程序,有時甚至優(yōu)于看設(shè)計文檔。4.10:對于switch語句下的case語句,如果因為特殊情況需要處理完一個case后進(jìn)入
22、下一個case處理,必須在該case語句處理完、下一個case語句前加上明確的注釋。說明:這樣比較清楚程序編寫者的意圖,有效防止無故遺漏break語句。4.11:注釋格式統(tǒng)一使用“/*/”,在“/*”之后至少有一個空格符,在“*/”之前至少有一個空格符。示例:if(.)/*代碼注釋*/5.標(biāo)識符命名5.1:標(biāo)識符的命名要清晰、明了,有明確含義,同時使用完整的單詞或大家基本可以理解的縮寫,避免使人產(chǎn)生誤解。說明:較短的單詞可通過去掉“元音”形成縮寫;較長的單詞可取單詞的頭幾個字母形成縮寫;一些單詞有大家公認(rèn)的縮寫。示例:如下單詞的縮寫能夠被大家基本認(rèn)可。temp可縮寫為tmp;flag可縮寫為f
23、lg;statistic可縮寫為stat;increment可縮寫為inc;message可縮寫為msg;5.2:除循環(huán)變量以外不允許使用i、j、k這樣的單個字符,循環(huán)控制變量統(tǒng)一使用有符號或者無符號的32位類型。說明:一般DSP會針對32位類型循環(huán)控制變量做優(yōu)化。5.3:為防止局部變量與全局變量重名,并增加變量名的可讀性,所有變量名必須按下面規(guī)則加頭以示說明。g全局變量(Global)(局部變量不加)p指針類型(pointer)v變量(Variable)c常量(Const)a數(shù)組(array)stu結(jié)構(gòu)體(struct)w雙字(word)s單字(short)c字節(jié)(char)b比特(bit)
24、u無符號(unsigned,有符號不寫)cs復(fù)數(shù),實、虛部都為16位(基帶常用)cw復(fù)數(shù),實、虛部都為32位(基帶常用)示例:gausNounTbl變量含義:g全局,a數(shù)組,u無符號,s單字,NounTbl變量名表示倒數(shù)表。5.4:命名規(guī)范必須與所使用的系統(tǒng)風(fēng)格保持一致,并在同一項目中統(tǒng)一,比如采用DSP的大小寫混排的方式,不要使用大小寫與下劃線混排的方式,示例:guwAdd_User不允許,uwAddUser、gausNounTbl允許。5.5:除非必要,不要用數(shù)字或較奇怪的字符來定義標(biāo)識符。示例:如下命名,使人產(chǎn)生疑惑。#define_EXAMPLE_0_TEST_#define_EXAM
25、PLE_1_TEST_voidset_sls00(BYTEsls);應(yīng)改為有意義的單詞命名#define_EXAMPLE_UNIT_TEST_#define_EXAMPLE_ASSERT_TEST_voidset_udt_msg_sls(BYTEsls);5.6:在同一軟件產(chǎn)品內(nèi),應(yīng)規(guī)劃好接口部分標(biāo)識符(變量、結(jié)構(gòu)、函數(shù)及常量)的命名,防止編譯、鏈接時產(chǎn)生沖突。說明:對接口部分的標(biāo)識符應(yīng)該有更嚴(yán)格限制,防止沖突。如可規(guī)定接口部分的變量與常量之前加上“模塊”標(biāo)識等。(此條規(guī)范主要適用于應(yīng)用層大型軟件)5.7:用正確的反義詞組命名具有互斥意義的變量或相反動作的函數(shù)等。說明:下面是一些在軟件中常用的
26、反義詞組。add/removebegin/endcreate/destroyinsert/deletefirst/lastget/releaseincrement/decrementput/getadd/deletelock/unlockopen/closemin/maxold/newstart/stopnext/previoussource/targetshow/hidesend/receivesource/destinationcut/pasteup/down5.8:除了編譯開關(guān)、頭文件等特殊應(yīng)用,不允許使用_EXAMPLE_TEST、EXAMPLE_TEST_、_EXAMPLE_TEST
27、_之類以下劃線開始或者結(jié)尾的定義。6.宏6.1:用宏定義表達(dá)式時,要使用完備的括號。示例:如下定義的宏都存在一定的風(fēng)險。#defineRECTANGLE_AREA(a,b)a*b#defineRECTANGLE_AREA(a,b)(a*b)#defineRECTANGLE_AREA(a,b)(a)*(b)正確的定義應(yīng)為:#defineRECTANGLE_AREA(a,b)(a)*(b)6.2:將宏所定義的多條表達(dá)式放在大括號中。示例:下面的語句只有宏的第一條表達(dá)式被執(zhí)行。為了說明問題,for語句的書寫稍不符規(guī)范。#defineINTI_RECT_VALUE(a,b)a=0;b=0;for(in
28、dex=0;indexRECT_TOTAL_NUM;index+)INTI_RECT_VALUE(rect.a,rect.b);正確的用法應(yīng)為:#defineINTI_RECT_VALUE(a,b)a=0;b=0;for(index=0;indexRECT_TOTAL_NUM;index+)INTI_RECT_VALUE(rectindex.a,rectindex.b);6.3:使用宏時,不允許參數(shù)發(fā)生變化。示例:如下用法可能導(dǎo)致錯誤。#defineSQUARE(a)(a)*(a)inta=5;intb;b=SQUARE(a+);/結(jié)果:a=7,即執(zhí)行了兩次增1。正確的用法是:b=SQUARE
29、(a);a+;/結(jié)果:a=6,即只執(zhí)行了一次增1。7.可讀性7.1:注意運算符的優(yōu)先級,并用括號明確表達(dá)式的操作順序,避免使用默認(rèn)優(yōu)先級。說明:防止閱讀程序時產(chǎn)生誤解,防止因默認(rèn)的優(yōu)先級與設(shè)計思想不符而導(dǎo)致程序出錯示例:下列語句中的表達(dá)式word=(high8)|low(1)if(a|b)&(a&c)(2)if(a|b)(c&d)(3)如果書寫為high8|lowa|b&a&c由于high8|low=(high8)|low,a|b&a&c=(a|b)&(a&c),(1)(2)不會出錯,但語句不易理解;aIbc&d=aI(bB-C-A),影響程序的可理解性;遞歸調(diào)用一般都占用較多的系統(tǒng)資源(如棧
30、空間);遞歸調(diào)用對程序的測試有一定影響。故除非為某些算法或功能的實現(xiàn)方便,應(yīng)減少沒必要的遞歸調(diào)用。9.3:防止將函數(shù)的參數(shù)作為工作變量。說明:將函數(shù)的參數(shù)作為工作變量,有可能錯誤地改變參數(shù)內(nèi)容,所以很危險。對必須改變的參數(shù),最好先用局部變量代之,最后再將該局部變量的內(nèi)容賦給該參數(shù)。示例:下函數(shù)的實現(xiàn)不太好。voidsum_data(unsignedintnum,int*data,int*sum)unsignedintcount;*sum=0;for(count=0;countnum;count+)*sum+=datacount;/sum成了工作變量,不太好。若改為如下,則更好些。voidsum
31、_data(unsignedintnum,int*data,int*sum)unsignedintcount;intsum_temp=0;for(count=0;countb)?a:b;改為如下就很清晰了。intmax(inta,intb)return(ab)?a:b);value=max(a,b);或改為如下。#defineMAX(a,b)(a)(b)?(a):(b)value=MAX(a,b);9.7:不要設(shè)計多用途面面俱到的函數(shù)。說明:多功能集于一身的函數(shù),很可能使函數(shù)的理解、測試、維護(hù)等變得困難。9.8:函數(shù)的功能應(yīng)該是可以預(yù)測的,也就是只要輸入數(shù)據(jù)相同就應(yīng)產(chǎn)生同樣的輸出。說明:帶有內(nèi)
32、部“存儲器”的函數(shù)的功能可能是不可預(yù)測的,因為它的輸出可能取決于內(nèi)部存儲器(如某標(biāo)記)的狀態(tài)。這樣的函數(shù)既不易于理解又不利于測試和維護(hù)。在C/C+語言中,函數(shù)的static局部變量是函數(shù)的內(nèi)部存儲器,有可能使函數(shù)的功能不可預(yù)測,然而,當(dāng)某函數(shù)的返回值為指針類型時,則必須是STATIC的局部變量的地址作為返回值,若為AUTO類,則返回為錯針。示例:如下函數(shù),其返回值(即功能)是不可預(yù)測的。unsignedintinteger_sum(unsignedintbase)unsignedintindex;staticunsignedintsum=0;/注意,是static類型的。/若改為auto類型,
33、則函數(shù)即變?yōu)榭深A(yù)測。for(index=1;index=base;index+)sum+=index;returnsum;9.9:編寫可重入函數(shù)時,應(yīng)注意局部變量的使用(如編寫C/C+語言的可重入函數(shù)時,應(yīng)使用auto即缺省態(tài)局部變量或寄存器變量)。說明:編寫C/C+語言的可重入函數(shù)時,不應(yīng)使用static局部變量,否則必須經(jīng)過特殊處理,才能使函數(shù)具有可重入性。9.10:編寫可重入函數(shù)時,若使用全局變量,則應(yīng)通過關(guān)中斷、信號量(即P、V操作)等手段對其加以保護(hù)。說明:若對所使用的全局變量不加以保護(hù),則此函數(shù)就不具有可重入性,即當(dāng)多個進(jìn)程調(diào)用此函數(shù)時,很有可能使有關(guān)全局變量變?yōu)椴豢芍獱顟B(tài)。示例:
34、假設(shè)Exam是int型全局變量,函數(shù)Squre_Exam返回Exam平方值。那么如下函數(shù)不具有可重入性。unsignedintexample(intpara)unsignedinttemp;Exam=para;/(*)temp=Square_Exam();returntemp;此函數(shù)若被多個進(jìn)程調(diào)用的話,其結(jié)果可能是未知的,因為當(dāng)(*)語句剛執(zhí)行完后,另外一個使用本函數(shù)的進(jìn)程可能正好被激活,那么當(dāng)新激活的進(jìn)程執(zhí)行到此函數(shù)時,將使Exam賦與另一個不同的para值,所以當(dāng)控制重新回到“temp=Square_Exam()”后,計算出的temp很可能不是預(yù)想中的結(jié)果。此函數(shù)應(yīng)如下改進(jìn)。unsign
35、edintexample(intpara)unsignedinttemp;申請信號量操作/若申請不到“信號量”,說明另外的進(jìn)程正處于Exam=para;/給Exam賦值并計算其平方過程中(即正在使用此temp=Square_Exam();/信號),本進(jìn)程必須等待其釋放信號后,才可繼釋放信號量操作/續(xù)執(zhí)行。若申請到信號,則可繼續(xù)執(zhí)行,但其它進(jìn)程必須等待本進(jìn)程釋放信號量后,才能再使用本信號。returntemp;9.11:非調(diào)度函數(shù)應(yīng)減少或防止控制參數(shù),盡量只使用數(shù)據(jù)參數(shù)。說明:本建議目的是防止函數(shù)間的控制耦合。調(diào)度函數(shù)是指根據(jù)輸入的消息類型或控制命令,來啟動相應(yīng)的功能實體(即函數(shù)或過程),而本身
36、并不完成具體功能??刂茀?shù)是指改變函數(shù)功能行為的參數(shù),即函數(shù)要根據(jù)此參數(shù)來決定具體怎樣工作。非調(diào)度函數(shù)的控制參數(shù)增加了函數(shù)間的控制耦合,很可能使函數(shù)間的耦合度增大,并使函數(shù)的功能不唯一。9.12:檢查函數(shù)所有參數(shù)輸入的有效性,檢查函數(shù)所有非參數(shù)輸入的有效性,如數(shù)據(jù)文件、公共變量等。說明:函數(shù)的輸入主要有兩種:一種是參數(shù)輸入;另一種是全局變量、數(shù)據(jù)文件的輸入,即非參數(shù)輸入。函數(shù)在使用輸入之前,應(yīng)進(jìn)行必要的檢查。9.13:函數(shù)名應(yīng)準(zhǔn)確描述函數(shù)的功能,使用動賓詞組為執(zhí)行某操作的函數(shù)命名。如果是OOP方法,可以只有動詞(名詞是對象本身)。示例:參照如下方式命名函數(shù)。voidprint_record(u
37、nsignedintrec_ind);intinput_record(void);unsignedcharget_current_color(void);說明:避免用含義不清的動詞如process、handle等為函數(shù)命名,因為這些動詞并沒有說明要具體做什么。函數(shù)的返回值要清楚、明了,讓使用者不容易忽視錯誤情況。說明:函數(shù)的每種出錯返回值的意義要清晰、明了、準(zhǔn)確,防止使用者誤用、理解錯誤或忽視錯誤返回碼。9.14:除非必要,最好不要把與函數(shù)返回值類型不同的變量,以編譯系統(tǒng)默認(rèn)的轉(zhuǎn)換方式或強(qiáng)制的轉(zhuǎn)換方式作為返回值返回。9.15:在調(diào)用函數(shù)填寫參數(shù)時,應(yīng)盡量減少沒有必要的默認(rèn)數(shù)據(jù)類型轉(zhuǎn)換或強(qiáng)制數(shù)據(jù)
38、類型轉(zhuǎn)換。說明:因為數(shù)據(jù)類型轉(zhuǎn)換或多或少存在危險。9.16:仔細(xì)分析模塊的功能及性能需求,并進(jìn)一步細(xì)分,同時若有必要畫出有關(guān)數(shù)據(jù)流圖,據(jù)此來進(jìn)行模塊的函數(shù)劃分與組織。說明:函數(shù)的劃分與組織是模塊的實現(xiàn)過程中很關(guān)鍵的步驟,如何劃分出合理的函數(shù)結(jié)構(gòu),關(guān)系到模塊的最終效率和可維護(hù)性、可測性等。根據(jù)模塊的功能圖或/及數(shù)據(jù)流圖映射出函數(shù)結(jié)構(gòu)是常用方法之一。9.17:改進(jìn)模塊中函數(shù)的結(jié)構(gòu),降低函數(shù)間的耦合度,并提高函數(shù)的獨立性以及代碼可讀性、效率和可維護(hù)性。優(yōu)化函數(shù)結(jié)構(gòu)時,要遵守以下原則:(1)不能影響模塊功能的實現(xiàn)。(2)仔細(xì)考查模塊或函數(shù)出錯處理及模塊的性能要求并進(jìn)行完善。(3)通過分解或合并函數(shù)來改
39、進(jìn)軟件結(jié)構(gòu)。(4)考查函數(shù)的規(guī)模,過大的要進(jìn)行分解。(5)降低函數(shù)間接口的復(fù)雜度。(6)不同層次的函數(shù)調(diào)用要有較合理的扇入、扇出。(7)函數(shù)功能應(yīng)可預(yù)測。(8)提高函數(shù)內(nèi)聚。(單一功能的函數(shù)內(nèi)聚最高)說明:對初步劃分后的函數(shù)結(jié)構(gòu)應(yīng)進(jìn)行改進(jìn)、優(yōu)化,使之更為合理。9.18:在多任務(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和
40、MSC等就不具備可重入函數(shù)庫,因為DOS是單用戶單任務(wù)操作系統(tǒng)。9.19:避免使用BOOL參數(shù)。說明:原因有二,其一是BOOL參數(shù)值無意義,TURE/FALSE的含義是非常模糊的,在調(diào)用時很難知道該參數(shù)到底傳達(dá)的是什么意思;其二是BOOL參數(shù)值不利于擴(kuò)充。還有NULL也是一個無意義的單詞。9.20:對于提供了返回值的函數(shù),在引用時最好使用其返回值。9.21:當(dāng)一個過程(函數(shù))中對較長變量(一般是結(jié)構(gòu)的成員)有較多引用時,可以用一個意義相當(dāng)?shù)暮甏?。說明:這樣可以增加編程效率和程序的可讀性。示例:在某過程中較多引用TheReceiveBufferFirstSocket.byDataPtr,則可以
41、通過以下宏定義來代替:#definepSOCKDATATheReceiveBufferFirstScoket.byDataPtr10.可測性10.1:在同一項目組或產(chǎn)品組內(nèi),要有一套統(tǒng)一的為集成測試與系統(tǒng)聯(lián)調(diào)準(zhǔn)備的調(diào)測開關(guān)及相應(yīng)打印函數(shù),并且要有詳細(xì)的說明。說明:本規(guī)則是針對項目組或產(chǎn)品組的。10.2:在同一項目組或產(chǎn)品組內(nèi),調(diào)測打印出的信息串的格式要有統(tǒng)一的形式。信息串中至少要有所在模塊名(或源文件名)及行號。說明:統(tǒng)一的調(diào)測信息格式便于集成測試。10.3:編程的同時要為單元測試選擇恰當(dāng)?shù)臏y試點,并仔細(xì)構(gòu)造測試代碼、測試用例,同時給出明確的注釋說明。測試代碼部分應(yīng)作為(模塊中的)一個子模塊,
42、以方便測試代碼在模塊中的安裝與拆卸(通過調(diào)測開關(guān))。說明:為單元測試而準(zhǔn)備。10.4:在進(jìn)行集成測試、系統(tǒng)聯(lián)調(diào)之前,要構(gòu)造好測試環(huán)境、測試項目及測試用例,同時仔細(xì)分析并優(yōu)化測試用例,以提高測試效率。說明:好的測試用例應(yīng)盡可能模擬出程序所遇到的邊界值、各種復(fù)雜環(huán)境及一些極端情況等。10.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ù)具體情況靈
43、活地設(shè)計斷言。示例:下面是C語言中的一個斷言,用宏來設(shè)計的。(其中NULL為0L)#ifdef_EXAM_ASSERT_TEST_/若使用斷言測試voidexam_assert(char*file_name,unsignedintline_no)printf(nEXAMAssertfailed:%s,line%un,file_name,line_no);abort();#defineEXAM_ASSERT(condition)if(condition)/若條件成立,則無動作NULL;else/否則報告exam_assert(_FILE_,_LINE_)#else/若不使用斷言測試#define
44、EXAM_ASSERT(condition)NULL#endif/*endofASSERT*/10.6:用斷言來檢查程序正常運行時不應(yīng)發(fā)生但在調(diào)測時有可能發(fā)生的非法情況。10.7:不能用斷言來檢查最終產(chǎn)品肯定會出現(xiàn)且必須處理的錯誤情況。說明:斷言是用來處理不應(yīng)該發(fā)生的錯誤情況的,對于可能會發(fā)生的且必須處理的情況要寫防錯程序,而不是斷言。如某模塊收到其它模塊或鏈路上的消息后,要對消息的合理性進(jìn)行檢查,此過程為正常的錯誤檢查,不能用斷言來實現(xiàn)。10.8:對較復(fù)雜的斷言加上明確的注釋。說明:為復(fù)雜的斷言加注釋,可澄清斷言含義并減少不必要的誤用。10.9:用斷言確認(rèn)函數(shù)的參數(shù)。示例:假設(shè)某函數(shù)參數(shù)中有
45、一個指針,那么使用指針前可對它檢查,如下。intexam_fun(unsignedchar*str)EXAM_ASSERT(str!=NULL);/用斷言檢查“假設(shè)指針不為空”這個條件./otherprogramcode10.10:用斷言保證沒有定義的特性或功能不被使用。示例:假設(shè)某通信模塊在設(shè)計時,準(zhǔn)備提供“無連接”和“連接”這兩種業(yè)務(wù)。但當(dāng)前的版本中僅實現(xiàn)了“無連接”業(yè)務(wù),且在此版本的正式發(fā)行版中,用戶(上層模塊)不應(yīng)產(chǎn)生“連接”業(yè)務(wù)的請求,那么在測試時可用斷言檢查用戶是否使用“連接”業(yè)務(wù)。如下。#defineEXAM_CONNECTIONLESS0/無連接業(yè)務(wù)#defineEXAM_CO
46、NNECTION1/連接業(yè)務(wù)intmsg_process(EXAM_MESSAGE*msg)unsignedcharservice;/*messageserviceclass*/EXAM_ASSERT(msg!=NULL);service=get_msg_service_class(msg);EXAM_ASSERT(service!=EXAM_CONNECTION);/假設(shè)不使用連接業(yè)務(wù)./otherprogramcode10.11:用斷言對程序開發(fā)環(huán)境(OS/Compiler/Hardware)的假設(shè)進(jìn)行檢查。說明:程序運行時所需的軟硬件環(huán)境及配置要求,不能用斷言來檢查,而必須由一段專門代碼處理。用斷言僅可對程序開發(fā)環(huán)境中的假設(shè)及所配置的某版本軟硬件是否具有某種功能的假設(shè)進(jìn)行檢查。如某網(wǎng)卡是否在系統(tǒng)運行環(huán)境中配置了,應(yīng)由程序中正式代
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 現(xiàn)代轉(zhuǎn)型中的城市社區(qū)治理框架
- 物流信息管理與大數(shù)據(jù)分析技術(shù)探索
- 現(xiàn)代企業(yè)人力資源管理的法律風(fēng)險防范
- 生物化學(xué)與營養(yǎng)學(xué)的交叉研究
- Unit1 They're monkeys(說課稿)-2023-2024學(xué)年外研版(三起)英語三年級下冊
- Unit 6 Touch your head(說課稿)-2024-2025湘少版(2024)英語三年級上冊
- 現(xiàn)代醫(yī)療背景下如何利用電信業(yè)務(wù)服務(wù)患者
- 淺析全球范圍內(nèi)如何開展綠色產(chǎn)品的采購管理
- 生物技術(shù)開啟農(nóng)業(yè)新紀(jì)元
- 生態(tài)修復(fù)技術(shù)在林業(yè)發(fā)展中的應(yīng)用
- 2025-2030年中國納米氧化鋁行業(yè)發(fā)展前景與投資戰(zhàn)略研究報告新版
- 教育強(qiáng)國建設(shè)規(guī)劃綱要(2024-2035年)要點解讀(教育是強(qiáng)國建設(shè)民族復(fù)興之基)
- 2025年度正規(guī)離婚協(xié)議書電子版下載服務(wù)
- 2025年貴州蔬菜集團(tuán)有限公司招聘筆試參考題庫含答案解析
- 煤礦安全生產(chǎn)方針及法律法規(guī)課件
- 2025年教科室工作計劃樣本(四篇)
- 2024年版古董古玩買賣合同:古玩交易稅費及支付規(guī)定
- 幼兒園費用報銷管理制度
- 【7歷期末】安徽省宣城市2023-2024學(xué)年七年級上學(xué)期期末考試歷史試題
- 春節(jié)后安全生產(chǎn)開工第一課
- 進(jìn)入答辯環(huán)節(jié)的高職應(yīng)用技術(shù)推廣中心申報書(最終版)
評論
0/150
提交評論