版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
正泰電源內(nèi)部文件禁止外傳軟體C語言編碼規(guī)范文件編號版本編制日期頁數(shù)CPS-WI-RD0019.V01
V022016-06-0322NUM擬制:簽名:日期:審核:經(jīng)理/總監(jiān)簽名:日期:審核:經(jīng)理/總監(jiān)簽名:日期:審核:經(jīng)理/總監(jiān)簽名:日期:審核:經(jīng)理/總監(jiān)簽名:日期:審核:經(jīng)理/總監(jiān)簽名:日期:批準(zhǔn):總經(jīng)理簽名:日期:
目錄TOC\o"1-2"\h\z\u更改歷史記錄 21、 總論 31.1目的 31.2 范圍 31.3 參考資料 31.4定義 31.5職責(zé) 32、規(guī)范內(nèi)容 42.1 程序結(jié)構(gòu)布局 42.2 程序的排版 72.3 注釋 92.4 命名規(guī)則 112.5 變量的使用 132.6 表達式 142.7 函數(shù) 172.8 預(yù)編譯/宏(Macro) 193、記錄相關(guān)文件表單、流程圖 193.1附錄一:常用單詞的縮寫 203.2附錄二:變量的常用前綴縮寫 203.3附錄三:常見常量的縮寫形式 20總論1.1目的軟件編程規(guī)范的目的和意義在于:1.1.1.統(tǒng)一公司嵌入式C語言軟件編程風(fēng)格1.1.2.提高軟件源程序的可讀性、可靠性和可重用性1.1.3.提高軟件源程序的質(zhì)量和可維護性1.1.4.減少軟件維護成本,最終提高軟件產(chǎn)品生產(chǎn)力范圍本文是針對整個ChintPower嵌入式C語言編程而制定的編碼規(guī)范。參考資料**********1.4定義1.4.1.本文中,對于每一項規(guī)則和建議,將采用如下的概念表達方法:1.4.1.1.首先給出規(guī)則或者建議簡要的文字描述。1.4.1.2.然后給出在要點基礎(chǔ)上延伸的說明文字。1.4.1.3.最后給出示例。給出正面例子,作為模版或文字描述的具體展示;或者給出反面例子,提示大家不要在編碼過程中出現(xiàn)類似情況。1.4.2.本文中使用的術(shù)語解釋如下:1.4.2.1.規(guī)則:編程時必須遵守的約定,規(guī)則項將會作為SQA的稽核內(nèi)容。1.4.2.2.建議:編程時必須加以考慮的約定。1.4.2.3.說明:對此規(guī)則或建議的必要的解釋。1.4.2.4.正例:對此規(guī)則或建議給出的正確例子。1.4.2.5.反例:對此規(guī)則或建議給出的反面例子。1.4.3.本規(guī)范分為規(guī)則性和建議性兩種:對于規(guī)則性規(guī)范,要求所有軟件開發(fā)人員嚴(yán)格執(zhí)行;對于建議性規(guī)范,各項目編程人員可以根據(jù)實際情況選擇執(zhí)行。1.4.4.由于規(guī)則是用來說明一般情況的,所以每條規(guī)則都是在一般情況下才有意義。如有特例需要違反規(guī)則,必須添加注釋予以說明!1.5職責(zé)本文之核準(zhǔn)、修改、發(fā)行、依文件管理準(zhǔn)則********處理。2、規(guī)范內(nèi)容 2.1 程序結(jié)構(gòu)布局2.1.1.目錄結(jié)構(gòu)【規(guī)則1-1】同類軟件工程項目,遵循統(tǒng)一的工程結(jié)構(gòu)?!菊f明】根據(jù)INVERTER工程需要和公司習(xí)慣,INVERTER軟件工程結(jié)構(gòu)如下所示,對于某些目錄,如:+support就可根據(jù)使用的編譯器環(huán)境確定是否存在,或者是否存在其他目錄配置文件。Project +app 應(yīng)用層代碼(Task,Interrupt)+kernel RTOS源代碼 +include 所需要包含的頭文件 +module 軟件模組 +driver 設(shè)備驅(qū)動程序+cpu 存放CPU相關(guān)的宏(I/0,Register定義) +output 存放最終的目標(biāo)文件 +debug 存放.obj文件等編譯器產(chǎn)生的文件 +cmd 存放編譯器配置文件 其他工程配置文件【規(guī)則1-2】在整個工程范圍內(nèi)調(diào)用的變量和函數(shù)(公用部分)聲明放在頭文件中,文件范圍內(nèi)調(diào)用的變量和函數(shù)(私有部分)聲明放在本文件的前面,函數(shù)范圍內(nèi)調(diào)用的變量聲明在函數(shù)體的開頭?!菊f明】為更好的進行信息隱藏,將模塊進行封裝,降低不同模塊之間的耦合度,方便程序的維護和重用,公用部分的聲明放在頭文件當(dāng)中,私有部分的聲明放在源文件當(dāng)中。2.1.2.文件布局【規(guī)則1-3】遵循統(tǒng)一的布局順序來書寫頭文件(*.h)?!菊f明】頭文件由三部分組成:版權(quán)和版本聲明;預(yù)處理塊;常數(shù)、變量以及函數(shù)等聲明。版權(quán)和版本的聲明位于頭文件和定義文件的開頭,主要內(nèi)容包括:(1)版權(quán)信息;(2)文件名稱、標(biāo)識符、摘要;(3)當(dāng)前版本號、作者/修改者、完成日期;(4)版本歷史信息。預(yù)處理塊的作用是為了防止頭文件被反復(fù)引用,因此,必須使用ifndef/define/endif結(jié)構(gòu)產(chǎn)生預(yù)處理塊。頭文件的所有聲明須遵循下面的順序:常量->全局宏—>全局?jǐn)?shù)據(jù)類型->外部引用->全局函數(shù)原型?!菊肯旅娴拇a是一個完整的頭文件模版,請依照下面的順序進行書寫:/*********************************************************************Copyright2009,ChintPower.FileName: Example.hDescription: ThisfileshowsastandardheadfileformatVersion: V1.0Author: NAME_EXPDate: 2009-10-19*********************************************************************///preprocessblock#ifndefMODEL_H#defineMODEL_H//constantdefinition#defineeUtilityTimer 0//GlobalMacro#definemGetExtIoBit(bit)((uwExtBuf0[0]&(1<<(bit)))>>bit)//globaldatatypeTypedefstruct{ INT8SbName[10];INT16UuwAge; }STUDENT;//externalreferenceExternINT16UuwInvVoltSampCnt;//globalfunctionprototypevoidsPowerOnMode(void);voidsStandbyMode(void);voidsBypassMode(void);#endif
【規(guī)則1-4】遵循統(tǒng)一的布局順序來書寫源文件(*.c)?!菊f明】定義文件由三部分組成:版權(quán)和版本聲明;對頭文件的引用;數(shù)據(jù)和代碼。版權(quán)和版本的聲明位于文件的開頭,主要內(nèi)容包括:(1)版權(quán)信息;(2)文件名稱、標(biāo)識符、摘要;(3)當(dāng)前版本號、作者/修改者、完成日期;(4)版本歷史信息。數(shù)據(jù)和代碼部分必須遵循下面的順序:常數(shù)和宏定義->數(shù)據(jù)類型聲明->變量聲明->表->函數(shù)原型->全局函數(shù)->局部函數(shù)。【正例】下面的代碼是一個完整的定義文件模版,按照下面的順序進行書寫:/*********************************************************************Copyright2008,SANTKCorporation.FileName: Example.cDescription: ThisfileshowsastandardsourcefileformatVersion: V1.0Author: NAME_EXPDate: 2009-10-19*********************************************************************//****head-filesincluding****/#include"kernel\kernel.h"#include"module\module.h"/****macrodefinition****/#definecSciTxRdy0#definecSciTxBusy1…………/****datatypedefinition****/typedef void(*pFunc)(void);typedef int(*pFunc1)(void);typedef void(*pFunc2)(unsignedint);typedef INT16U(*pFunc3)(void);…………/****variabledefinition****/INT16S wCmdLength;INT8U *pubCmdIn0;INT8U *pubCmdIn1;…………/****table****/constINT8S bCmdTabArray[MAX_CMD_SIZE][2]={"AG","AS","CT","CV","EX","FS","LS","ON", "PF","PS","PW","Q1","Q2","Q3", "Q7","QD","QM","QP","VS","WA","WH"};…………/****functionprototype****/INT8UsubSnatchGraph(void);voidsTestCmd(void);…………/****globalfunction****//*********************************************************************Functionname: INT8UsubSnatchGraph(void)Description: SaveINVERTERinternalvariantvalueCalls: CalledBy:INVInterrupt()Parameters: voidReturn: INT8U*********************************************************************/INT8UsubSnatchGraph(void){ …..}/****localfunction****//*********************************************************************Functionname: voidsTestCmd(void)Description: testcommandforsci.Calls: sSetBatTestTime();CalledBy:Parameters: voidReturn: void*********************************************************************/voidsTestCmd(void){ …………}2.1.3.文件容量『建議1-1』每個源程序大小應(yīng)控制在3000LOC以內(nèi)。2.2 程序的排版版式雖然不會影響程序的功能,但會影響可讀性。程序的版式追求清晰、美觀,是程序風(fēng)格的重要構(gòu)成因素。2.2.1.空白行使用【規(guī)則2-1】文件之中不得存在無規(guī)則的空行,函數(shù)與函數(shù)之間的空行為2行,在函數(shù)體內(nèi)部,在邏輯上獨立的兩個語句塊可適當(dāng)空行,一般為1行。2.2.2.語句中的空格【規(guī)則2-2】函數(shù)名之后不要留空格,緊跟左括號‘(’,以與關(guān)鍵字區(qū)別。【規(guī)則2-3】‘(’向后緊跟,‘)’向前緊跟,‘;’向前緊跟,緊跟處不留空格,但和后面內(nèi)容留有一個空格,‘,’前后緊跟?!菊f明】向后緊跟即與后面的內(nèi)容直接無空格,向前緊跟即與前面的內(nèi)容無空格,前后緊跟說明與前后的內(nèi)容都無空格?!菊縡or(i=0;i<cMaxNum;i++){sModelFunction(bParameterA,bParameterB);}【規(guī)則2-4】二元操作符的前后必須添加空格。【說明】二元操作符包括:賦值操作符、比較操作符、算術(shù)操作符、邏輯操作符、位域操作符。如“=”、“+=”“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等?!疽?guī)則2-5】一元操作符前后不加空格?!菊f明】一元操作符包括“!”、“~”、“++”、“--”、“&”(地址運算符)“[]”、“.”、“->”這類操作符?!疽?guī)則2-6】必須將修飾符*和&緊靠變量名,而不是靠近數(shù)據(jù)類型名。【正例】INT16U*puwVariableA;【反例】INT16U*puwVariableA;2.2.3.語句中的縮進【規(guī)則2-7】統(tǒng)一使用4個字符的縮進,并使用空格代替TAB鍵?!疽?guī)則2-8】程序的分界符‘{’和‘}’必須獨占一行并且位于同一列,同時與引用它們的語句左對齊;{}之內(nèi)的代碼塊在‘{’下一行的右邊四個空格處對齊?!疽?guī)則2-9】對于單條語句的注釋,且注釋內(nèi)容不超過1行的情況下,可以在語句之后進行行注釋。對于需要在代碼上方添加的注釋,應(yīng)保證注釋與代碼必須保持相同的縮進?!菊繕?biāo)準(zhǔn)的寫法是://judgeifinverterperiodisinnoise,yes,updaterelevantvariable,no,return.if(wInvPrdNewTemp<cPrd200Hz){….}wInvPrdNew=wInvPrdNewTemp;//updatecrosszerovalue……2.2.4.代碼行【規(guī)則2-10】代碼行長度必須控制在80個字符以內(nèi)(含空格)?!疽?guī)則2-11】if、for、while、do等語句自占一行,執(zhí)行語句不得緊跟其后。不論執(zhí)行語句有多少都必須要加{}。【反例】if的執(zhí)行語句緊跟其后:if(pCanRxIn==&wCanRxBuf[cCanRxBufSize-1])pCanRxIn=wCanRxBuf;【正例】雖然執(zhí)行語句只有一行,但仍然要加“{}”,if語句自占一行:if(pCanRxIn==&wCanRxBuf[cCanRxBufSize-1]){pCanRxIn=wCanRxBuf;}【規(guī)則2-12】長表達式(超過80個字符)要在低優(yōu)先級操作符處拆分成新行,操作符放在新行之首(以便突出操作符);拆分出的新行要進行縮進,使排版易讀、整齊?!菊块L賦值語句拆分:dwPFCTemp=(INT32S)((INT32S)wKvd_1*wVm_P\ +(INT32S)wKvd_2*wVm_P_1+(INT32S)wKvn_1*wVerr_P\ +(INT32S)wKvn_2*wVerr_P_1+(INT32S)wVm_P_Res);長判斷語句拆分:elseif((swGetPBusAvgVoltNew()>cBus120v)\&&(swGetNBusAvgVoltNew()>cBus120v)\&&(wPreChgCnt>=500))【規(guī)則2-13】一行代碼只做一件事情,如只定義一個變量,或只寫一條語句?!菊f明】也就是說一行代碼只允許有一個語句;不能在一行代碼同時定義多于一個的變量。 這樣做的目的是為了使代碼便于閱讀和注釋。2.3 注釋注釋應(yīng)該和編碼同步,并保持和代碼的一致。C語言的塊注釋符為“/*”“*/”,行注釋符用“//”。注釋的內(nèi)容通常有:(1)版本、版權(quán)聲明;(2)函數(shù)接口說明;(3)重要代碼行、段落意義說明。2.3.1.注釋語言【規(guī)則3-1】注釋必須使用英文,且注釋要言簡意賅。2.3.2.文件頭部注釋【規(guī)則3-2】文件頭部必須進行注釋,包括:.h文件、.c文件、.cpp文件等?!菊f明】文件頭部注釋應(yīng)包含的基本內(nèi)容如下:Copyright:Filename:Description:Author:Version:Date:【正例】/*********************************************************************Copyright2009,ChintCorporation.FileName: Linemodule.hDescription: definefunctionnameVersion: V1.0Author: NAME_EXPDate: 2009-10-19*********************************************************************/2.3.3.函數(shù)頭部注釋【規(guī)則3-3】函數(shù)頭部要給出的注釋包括:函數(shù)名稱、功能、輸入?yún)?shù)、輸出參數(shù)、返回值、調(diào)用說明、修改歷史,其中函數(shù)名和描述必須要寫,其他項可根據(jù)函數(shù)實體的實際情況而定。【說明】函數(shù)頭部注釋應(yīng)包含的基本內(nèi)容如下:Functionname:Description:Calls:CalledBy:Parameters:Return:【正例】/*********************************************************************Functionname: INT8UsubSnatchGraph(void)Description:SaveINVERTERinternalvariantvalueCalls: CalledBy:PFCInterrupt()Parameters:voidReturn: INT8U*********************************************************************/2.3.4.全局變量注釋【規(guī)則3-4】全局變量必須進行注釋,內(nèi)容一般包括:功能、取值范圍、訪問信息、注意事項。對于不能充分自注釋的局部變量,也應(yīng)該要加注釋予以說明?!菊?/RealvoltageofR,S,Tphase,andiscalledbyinterruptINT16UuwRLineVoltReal=0;INT16UuwSLineVoltReal=0;INT16UuwTLineVoltReal=0;2.3.5.語句注釋【規(guī)則3-5】在功能相同的語句段前添加注釋說明該段語句的功能。【正例】//updatecrossingzerovaluewInvPrdNew=wInvPrdNewTemp;wInvPrdCntNew=wInvPrdCntNewTemp;wInvZeroTimeNew=wInvZeroTimeNewTemp;wInvZeroTimeOld=wInvZeroTimeNew;【規(guī)則3-6】對于多層嵌套、多個分支的語句塊必須進行注釋。【說明】這些語句往往是理解一段代碼的關(guān)鍵,因此,必須進行清晰的注釋,對于軟件工程師來說,讀這些注釋要比讀開發(fā)文檔的效果好得多。【正例】下面這段代碼是一個if條件判斷語句塊,里面又有多層嵌套,因此,必須進行清晰的注釋。如下所示,在每一個嵌套部分對功能進行描述。//checkifpqisfullif(pq->length==pq->size){//whenfullqueuewillcoverthefrontofqueue.if(cOverWrOpt==QUE_COVER_FIRST) { *(pq->pIn)=data;//checkifpInpointedtothetailofqueue if(pq->pIn==pq->pStart+pq->size) { pq->pIn=pq->pStart; } else { pq->pIn++; } pq->pOut=pq->pIn; }//whenfulldatawillcoverthelastofqueueelseif(cOverWrOpt==QUE_COVER_LAST) { //checkifpInpointedtotheheadofqueueif(pq->pIn==pq->pStart) { *(pq->pStart+pq->size)=data; } else { *(pq->pIn-1)=data; } } return(QUE_BUF_FULL);}2.3.6.修改程序注釋【規(guī)則3-7】修改標(biāo)簽采用統(tǒng)一的格式://Modifiernameyyyymmdd+附加說明【正例】單獨行修改標(biāo)簽:INT16SwTemp; //panna20080130段修改標(biāo)簽://panna20080130beginstructBOX{INT16Si; INT16Sj; INT16SwLength; INT16SwWidth; };//panna20080130end2.3.7.其他建議『建議3-1』注釋是對代碼的“提示”,而不是文檔。程序中的注釋不可喧賓奪主,注釋太多了會讓人眼花繚亂。注釋的花樣要少?!航ㄗh3-2』發(fā)布release版本時應(yīng)刪除無用的注釋和測試代碼。2.4 命名規(guī)則公司的命名規(guī)則遵守匈牙利命名法,該命名規(guī)則的主要思想是“在變量和函數(shù)名中加入前綴以增強人們對程序的理解”。2.4.1.常量命名【規(guī)則4-1】有意義的常數(shù)需要用常量來表示,以增強可讀性,常量需要以小寫c開頭。常用縮寫見HYPERLINK附錄1?!航ㄗh4-4』對于無符號的變量前面加u,用以區(qū)別有符號的變量?!菊f明】要對無符號的變量與有符號的變量、常量加以區(qū)分,就應(yīng)該添加某些前綴。如unsignedbyte:ubunsignedword:uw unsigneddoubleword:udw而有符號的變量前面不加u,用以跟無符號的變量、常量區(qū)分。如signedbyte:bsignedword:wsigneddoubleword:dw2.5 變量的使用2.5.1.變量的使用【規(guī)則5-1】定義變量時,必須明確其含義、作用、取值范圍,以及同其他變量之間的關(guān)系。【反例】INT8U ubLineZeroCnt;for(ubLineZeroCnt=0;ubLineZeroCnt<300;ubLineZeroCnt++){………}結(jié)果會導(dǎo)致變量ubLineZeroCnt發(fā)生越界現(xiàn)象。因此,在定義變量的時候應(yīng)該首先明確該變量的取值范圍,如本例中,需要將INT8U ubLineZeroCnt;改為INT16UuwLineZeroCnt;【規(guī)則5-2】編寫可重入函數(shù)時,若使用全局變量,必須使用關(guān)中斷,信號量等手段對其加以保護?!菊f明】如果不對全局變量加以保護,則此函數(shù)就不具備可重入性,在多個進程調(diào)用該函數(shù)時,很有可能使有關(guān)全局變量的值發(fā)生預(yù)料之外的改變。【正例】OS_ENTER_CRITICAL();//closeglobalinterruptuwDroopStatus=cDroopBypass;OS_EXIT_CRITICAL();//openglobalinterrupt【規(guī)則5-3】嚴(yán)禁使用未經(jīng)初始化的變量作為右值,尤其是指針變量?!菊f明】任何指針變量剛被創(chuàng)建時不會自動成為NULL指針,它的缺省值是隨機的,它會亂指一氣。所以,指針變量在創(chuàng)建的同時應(yīng)當(dāng)被初始化,要么將指針設(shè)置為NULL,要么讓它指向合法的內(nèi)存?!疽?guī)則5-4】構(gòu)造僅有一個模塊或函數(shù)可以修改、創(chuàng)建,而其余有關(guān)模塊或函數(shù)只訪問的公共變量,防止多個不同模塊或函數(shù)都可以修改、創(chuàng)建同一公共變量的現(xiàn)象?!菊f明】降低系統(tǒng)中全局變量之間耦合度??梢员苊庠L問全局變量時的錯誤操作。例如使用統(tǒng)一的Get和Set函數(shù)對一系列全局變量進行“讀”和“寫”的操作?!菊坷煤瘮?shù)swGetRLineVolt來獲取變量wRLineVolt的值。INT16S swGetRLineVolt(void){ return(wRLineVolt);}【規(guī)則5-5】對于有數(shù)據(jù)類型轉(zhuǎn)換的賦值,必須要進行強制的數(shù)據(jù)類型轉(zhuǎn)換,避免隱式的數(shù)據(jù)轉(zhuǎn)換?!菊f明】對于有要數(shù)據(jù)類型轉(zhuǎn)換情況,一定要使用(數(shù)據(jù)類型)數(shù)據(jù)的方式進行轉(zhuǎn)換?!痉蠢縲RInvVoltSample=((INT32S)wRInvVoltSample*wADCCoefA)>>14;wRInvVoltSample為INT16S型的,而((INT32S)wRInvVoltSample*wADCCoefA)>>14產(chǎn)生的結(jié)果為INT32S型,會造成隱形的數(shù)據(jù)轉(zhuǎn)換?!菊繛榱吮苊馍厦娴碾[形數(shù)據(jù)轉(zhuǎn)換,應(yīng)該用如下的強制數(shù)據(jù)轉(zhuǎn)換來轉(zhuǎn)換結(jié)果:wRInvVoltSample=(INT16S)(((INT32S)wRInvVoltSample*wADCCoefA)>>14);2.5.2.其他建議『建議5-1』只在文件范圍內(nèi)使用,具有整個生命周期的變量需要加上static限定2.6 表達式C語言的運算符有數(shù)十個,運算符的優(yōu)先級與結(jié)合律如表6-1所示。注意一元運算符+-*的優(yōu)先級高于對應(yīng)的二元運算符。表6-1運算符的優(yōu)先級和結(jié)合律優(yōu)先級運算符結(jié)合律從高到低排列()[]->.從左至右!~++--(類型)sizeof+-*&從右至左*/%從左至右+-從左至右<<>>從左至右<<=>>=從左至右==!=從左至右&從左至右^從左至右|從左至右&&從左至右||從右至左?:從右至左=+=-=*=/=%=&=^=|=<<=>>=從左至右,從左至右2.6.1.復(fù)合表達式【規(guī)則6-1】在有多個不同類型運算符的表達式中,必須使用括號對運算優(yōu)先級進行限制,避免使用默認(rèn)的優(yōu)先級順序。【說明】雖然C語言規(guī)定了各種運算符之間的優(yōu)先級順序,但是,每個人都對該順序熟爛于心是不可能的。因此,為了保證正確性也提高代碼的可讀性,在表達式中有多個不同類型運算符的時候,必須使用括號來限制優(yōu)先級?!菊肯旅娴倪\算式包含了減法、乘法、移位、強制類型轉(zhuǎn)換四種運算:wLnPrdNewTemp=(INT16S)(((INT32U)(wLineZeroTimeNewTemp–wLineZeroTimeOld)*27962)>>16);//calculatelinevoltageperiod【規(guī)則6-2】對于涉及到除法運算的表達式,一定要校驗除數(shù)表達式(或變量)是否為0;對于涉及到取余運算的表達式,一定要校驗運算符兩邊的數(shù)是否為整數(shù)。2.6.2.if表達式【規(guī)則6-3】布爾變量只應(yīng)該和FALSE進行比較?!菊f明】TRUE和FALSE的定義值是與語言環(huán)境相關(guān)的,是可以被重定義的。本規(guī)則正例中的格式只適用于布爾類型的變量或表達式與0比較的情況?!菊考僭O(shè)ubTest為布爾型變量,判斷ubTest的值用下面的表達式:if(ubTest==FALSE)//表示判斷ubTest是否為假if(ubTest!=FALSE)//表示判斷ubTest是否為真【規(guī)則6-4】不可以將浮點型變量用“==”或“!=”與任何數(shù)值進行比較?!菊f明】float和double類型的變量都有精度的限制,因此,不能直接用來同數(shù)值進行等于或不等于的比較,應(yīng)設(shè)法轉(zhuǎn)化為大于并且小于某一個精度范圍?!疽?guī)則6-5】指針型變量與零值的比較應(yīng)該和NULL進行比較。2.6.3.for循環(huán)語句【規(guī)則6-6】不可以在for循環(huán)體的內(nèi)部修改循環(huán)變量,防止for循環(huán)失去控制?!菊f明】for循環(huán)內(nèi)部的循環(huán)變量不可在循環(huán)語句外部進行修改操作,如果操作不當(dāng)可能會導(dǎo)致該循環(huán)不可控制,使得循環(huán)失效?!痉蠢縡or(I=0;I<128;i++){*Dest++=*Source++; i++;//maybeletthecycleuncontrollable!}2.6.4.switch語句【規(guī)則6-7】switch語句中的每個case塊必須有break,否則不同case塊會重疊;switch語句中的default塊不可以省略,default塊也必須有break語句?!菊f明】漏掉break語句會造成程序錯誤。多個分支語句處理同一種情況的時候,即需要case塊的重疊時,可以去掉break,但必須有注釋說明?!菊縮witch(uwFanDetectCnt){case0: sClrFanClkCnt(); break; case100: sFan0LockChk(suwGetFanClkCnt(),230,5); break; case1250: sClrFanClkCnt(); break; case1350: sFan1LockChk(suwGetFanClkCnt(),230,5); break; default: break;}2.6.5.其它建議『建議6-1』循環(huán)變量的取值范圍設(shè)置為半開半閉區(qū)間。【說明】當(dāng)循環(huán)變量的取值范圍設(shè)置為半開半閉區(qū)間時,循環(huán)的次數(shù)就是兩個值的差值,使程序易讀并且不容易出錯?!菊肯旅娴睦又校h(huán)變量i的循環(huán)條件為I<wLength,而不是I<=wLength,這樣wLength的值就是循環(huán)的次數(shù)。for(I=0;I<wLength;i++){*(puwDestBuf++)=*(puwSourceBuf++);}如果將循環(huán)條件改為I<=wLength,那么循環(huán)的次數(shù)為wLength+1,閱讀時容易出錯?!航ㄗh6-2』建議使用條件判斷的嵌套層數(shù)不大于5層?!航ㄗh6-3』使用簡單的復(fù)合語句,不要使用太復(fù)雜和多用途的復(fù)合語句?!航ㄗh6-4』for語句需要拆分時可拆分為三行?!航ㄗh6-5』當(dāng)使用永久循環(huán)時,盡量使用“While(1)”代替“for(;;)”『建議6-6』避免用do/while,可用While與break代替。『建議6-7』在多重循環(huán)中,如果有可能,應(yīng)當(dāng)將最長的循環(huán)放在最內(nèi)層,最短的循環(huán)放在最外層,以減少CPU跨循環(huán)層的次數(shù)。2.7 函數(shù)2.7.1.參數(shù)規(guī)則【規(guī)則7-1】參數(shù)的書寫要完整,不能只寫參數(shù)的類型而省略參數(shù)名字。如果函數(shù)沒有參數(shù),則用void填充。參數(shù)的個數(shù)要盡量控制在5個以內(nèi)。【說明】書寫完整,不能省略參數(shù)名;命名要合理,即明確表達出參數(shù)的作用;更有利于程序的可讀性順序要恰當(dāng),即一個函數(shù)有多個參數(shù)的時候,順序要遵循程序員的習(xí)慣,例如輸入?yún)?shù)放在前面,輸出參數(shù)放在后面。【正例】voidsCanCopy(CANFRAME*pSource,CANFRAME*pDestination)輸入?yún)?shù)為source,輸出參數(shù)為destination?!疽?guī)則7-2】如果參數(shù)是指針,且僅作輸入用,則必須在類型前加const,以防止該指針在函數(shù)體內(nèi)被意外修改。【正例】VoidsBatUnderVoltSetVSLoad(constINT16U*puwBatUnderPointsTable,INT16UuwLoadLevel1,INT16UuwLoadLevel2)指針變量puwBatUnderPointsTable在這里僅作為輸入作用,為防止該值在使用過程中被意外改變,應(yīng)該加const修飾?!疽?guī)則7-3】當(dāng)結(jié)構(gòu)變量作為參數(shù)時,應(yīng)傳送結(jié)構(gòu)的指針而不傳送整個結(jié)構(gòu)體?!菊f明】一個函數(shù)被調(diào)用的時候,形參會被一個個壓入被調(diào)函數(shù)的堆棧中,在函數(shù)調(diào)用結(jié)束以后再彈出。一個結(jié)構(gòu)所包含的變量往往比較多,直接以一個結(jié)構(gòu)為參數(shù),壓棧出棧的內(nèi)容就會太多,不但占用堆??臻g,如果使用不當(dāng)還可能導(dǎo)致堆棧的溢出,而且影響代碼執(zhí)行效率,。但是使用結(jié)構(gòu)的指針作為參數(shù),由于指針的長度是固定不變的,結(jié)構(gòu)的大小就既不會影響代碼執(zhí)行的效率,也不會過多地占用堆??臻g?!痉蠢縑oidsCanCopy(CANFRAMEstSource,CANFRAMEstDestination)【正例】VoidsCanCopy(CANFRAME*pstSource,CANFRAME*pstDestination)2.7.2.返回值規(guī)則【規(guī)則7-4】返回值的類型不能省略?!菊f明】在C語言中,返回值的類型沒有被定義時,默認(rèn)為整型,但是從寫法上,容易被誤認(rèn)為是void類型,會引起不必要的麻煩,所以,函數(shù)的返回值類型不能省略。【反例】sQInit(QUEUE*pstPq,INT8U*pubStart,INT16UuwSize)返回類型系統(tǒng)默認(rèn)為整型;【正例】voidsQInit(QUEUE*pstPq,INT8U*pubStart,INT16UuwSize)返回類型為空;因此,函數(shù)的返回值為空時也不能省略?!疽?guī)則7-5】對于有返回值的函數(shù),函數(shù)的每一個分支都必須有返回值?!菊f明】防止出現(xiàn)函數(shù)無值返回,造成返回值的不可預(yù)知性?!痉蠢縄NT8UsubSciGetRxData(INT8UubSciid){if(ubSciid==0){ return(subGetSciRxData0()); } if(ubSciid==1) { }}【正例】INT8UsubSciGetRxData(INT8UubSciid){ if(ubSciid==0) { return(subGetSciRxData0()); } if(ubSciid==1) { return(subGetSciRxData1()); }return(0);}【規(guī)則7-6】不要返回函數(shù)內(nèi)堆棧內(nèi)存的指針。2.7.3.函數(shù)內(nèi)部規(guī)則【規(guī)則7-7】禁止將函數(shù)的參數(shù)作為工作變量?!菊f明】如果將函數(shù)的參數(shù)作為工作變量,那么參數(shù)內(nèi)容在函數(shù)體內(nèi)會被改變,所以很危險。對必須改變的參數(shù),最好先用局部變量作為工作變量,處理結(jié)束后,將該局部變量的內(nèi)容在最后賦給該參數(shù)。2.7.4.其它建議『建議7-1』不要使用類型和數(shù)目不確定的參數(shù)?!航ㄗh7-2』盡量在文件中僅包含該文件用到的頭文件。『建議7-3』函數(shù)的規(guī)??刂圃?00行以內(nèi)。【說明】200行不包括注釋和空格行?!航ㄗh7-4』函數(shù)的功能是可預(yù)測的,即每種輸入產(chǎn)生確定的輸出。2.8 預(yù)編譯/宏(Macro)【規(guī)則8-1】用宏定義表達式時,要使用完備的括號,必要時使用大括號?!菊f明】當(dāng)宏帶有變量的時候,由于宏是簡單的替代,如果沒有完備的括號,宏是存在風(fēng)險的。另外,當(dāng)宏包含的語句不止一句的時候,必須使用大括號把語句塊包含起來。【正例】完備的括號:#definemGetExtIOBit(bit)((uwExternalBuf[0]&(1<<(bit)))>>(bit))多條語句(注意換行符“\”的使用):#definemWriteExtIO0(iset)\{\outportbuffer0=(iset);\uwExternalBuf[0]=outportbuffer0;\}【反例】不完備的括號:#definemGetExtIOBit(bit)(uwExternalBuf[0]&(1<<(bit)))>>(bit)多條語句:#definemWriteExtIO0(iset)outportbuffer0=(iset);uwExternalBuf[0]=outportbuffer0【規(guī)則8-2】調(diào)用宏時,不允許宏參數(shù)發(fā)生變化【說明】當(dāng)宏的參數(shù)不止一次被帶入計算,那么第二次替代時,參數(shù)值已經(jīng)被改變,將得不到需要的結(jié)果。【反例】#definemSQUARE(a)((a)*(a))inta=5;intb;b=mSQUARE(a++);結(jié)果:a=7,即執(zhí)行了兩次增1。【正例】b=mSQUARE(a);a++;結(jié)果:a=6,即只執(zhí)行了一次增1?!疽?guī)則8-3】在程序開頭,為編譯控制符編寫#define與#undef語句?!疽?guī)則8-4】在#include指示符中,不得使用絕對路徑,允許自動編譯選擇?!菊f明】在編譯器環(huán)境中設(shè)定絕對路徑,程序中需要使用相對路徑包含頭文件。【正例】#include“Kernel\OS_HEAD.H”,在編譯器中設(shè)置絕對路徑:D:\testc\SplitPhaseDriver?!痉蠢渴褂媒^對路徑包含頭文件#include“D:\test
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 犬皮膚病診治
- 膽囊切除手術(shù)后的飲食與生活注意
- 麥子課件教案教學(xué)課件
- 匆匆的 課件教學(xué)課件
- 采購小組長述職報告
- 高三化學(xué)一輪復(fù)習(xí) 第一章 第1講 考點三 分散系 膠體 課件
- 4.1.1原電池的工作原理上學(xué)期人教版(2019)選擇性必修1
- 腕手關(guān)節(jié)僵硬的康復(fù)治療
- 不玩危險物品教案反思
- 甲狀腺核磁共振成像結(jié)果
- 不抱怨的世界(課堂PPT)
- 企業(yè)盈利能力分析——以青島啤酒股份有限公司為例
- 消火栓滅火器檢查記錄表
- 岸墻、翼墻及導(dǎo)水墻砼澆筑方案
- 第三章_配位化學(xué)
- 中國話-完整版PPT課件
- 纏論基本概念圖解(推薦)
- 海瑞克英文翻譯
- 培訓(xùn)師經(jīng)常用到的七大培訓(xùn)方式及操作方法
- 魯教版美術(shù)九年級下冊教學(xué)設(shè)計
- 模具斜與蝕紋關(guān)系對照表
評論
0/150
提交評論