成都信息工程學(xué)院非計算機專業(yè)c語言初學(xué)者編程規(guī)_第1頁
已閱讀1頁,還剩25頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p>  成都信息工程學(xué)院非計算機專業(yè)</p><p>  C語言初學(xué)者編程規(guī)范(學(xué)生用)</p><p>  成都信息工程學(xué)院計算機基礎(chǔ)教學(xué)部</p><p>  對于程序員來說,能工作的代碼并不等于“好”的代碼?!昂谩贝a的指標(biāo)很多,包括易讀、易維護、易移植和可靠等。其中,可靠性對嵌入式系統(tǒng)非常重要,尤其是在那些對安全性要求很高的系統(tǒng)中,如飛行器、汽

2、車和工業(yè)控制中。這些系統(tǒng)的特點是:只要工作稍有偏差,就有可能造成重大損失或者人員傷亡。一個不容易出錯的系統(tǒng),除了要有很好的硬件設(shè)計(如電磁兼容性),還要有很健壯或者說“安全”的程序。</p><p>  然而,很少有程序員知道什么樣的程序是安全的程序。很多程序只是表面上可以干活,還存在著大量的隱患。當(dāng)然,這其中也有C語言自身的原因。因為C語言是一門難以掌握的語言,其靈活的編程方式和語法規(guī)則對于一個新手來說很可能會

3、成為機關(guān)重重的陷阱。同時,C語言的定義還并不完全,即使是國際通用的C語言標(biāo)準(zhǔn),也還存在著很多未完全定義的地方。要求所有的嵌入式程序員都成為C語言專家,避開所有可能帶來危險的編程方式,是不現(xiàn)實的。最好的方法是有一個針對安全性的C語言編程規(guī)范,告訴程序員該如何做。</p><p>  本規(guī)范在制定過程中,主要參考了業(yè)界比較推崇的《華為軟件編程規(guī)范和范例》和《MISRA 2004規(guī)則》,適合于非計算機專業(yè)的C語言初學(xué)者

4、使用,目的在于在教學(xué)中培養(yǎng)學(xué)生良好的編程規(guī)范和意識、素質(zhì),促進所設(shè)計程序安全、健壯、可靠、可讀與可維護(程序簡單、清晰)??紤]到面向的是初學(xué)者,為便于教學(xué)和課程考核操作,本規(guī)范中的要求比較基本。事實上,很多公司都有自己規(guī)定的代碼風(fēng)格,包括命名規(guī)則、縮進規(guī)則等,學(xué)生參加工作后,應(yīng)再進一步學(xué)習(xí)和應(yīng)用公司的規(guī)范。</p><p>  建議學(xué)生在學(xué)習(xí)本規(guī)范的同時,花點時間閱讀本規(guī)范的參考文獻原文,特別是熟讀本規(guī)范的參考文

5、獻之一的《“安全第一”的C語言編程規(guī)范》,深刻理解編程規(guī)范與程序安全、健壯、可靠、可讀、可維護間的關(guān)系和作用,在學(xué)習(xí)和工作中養(yǎng)成良好的編程風(fēng)格。</p><p><b>  1 排版</b></p><p>  1.1 嚴(yán)格采用階梯層次組織程序代碼</p><p>  函數(shù)或過程的開始、結(jié)構(gòu)的定義及循環(huán)、判斷等語句中的代碼都要采用縮進風(fēng)格,ca

6、se 語句下的情況處理語句也要遵從語句縮進要求。</p><p>  程序塊的分界符(如C/C++ 語言的大括號‘{’ 和‘}’)應(yīng)各獨占一行并且位于同一列,同時與引用它們的語句左對齊。在函數(shù)體的開始、類的定義、結(jié)構(gòu)的定義、枚舉的定義以及if 、for 、do 、while 、switch 、case 語句中的程序都要采用如上的縮進方式。</p><p>  各層次縮進的風(fēng)格采用TAB縮進

7、(TAB寬度原則上使用系統(tǒng)默認值,TC使用8空格寬度,VC使用4空格寬度)。示例:</p><p>  if (x is true)</p><p><b>  {</b></p><p><b>  we do y</b></p><p><b>  }</b></p&

8、gt;<p><b>  else</b></p><p><b>  {</b></p><p>  if (a > b)</p><p><b>  {</b></p><p><b>  ...</b></p>&l

9、t;p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p><b>  ...</b></p><p><b>  }</b></p>&l

10、t;p><b>  }</b></p><p><b>  和:</b></p><p>  if (x == y)</p><p><b>  {</b></p><p><b>  ...</b></p><p><

11、b>  }</b></p><p>  else if (x > y)</p><p><b>  {</b></p><p><b>  ...</b></p><p><b>  }</b></p><p><b>

12、  else</b></p><p><b>  {</b></p><p><b>  ....</b></p><p><b>  }</b></p><p>  注意,右括號所在的行不應(yīng)當(dāng)有其它東西,除非跟隨著一個條件判斷。也就是do-while語句中的“wh

13、ile”,象這樣:</p><p><b>  do</b></p><p><b>  {</b></p><p>  body of do-loop</p><p>  } while (condition);</p><p>  說明:代碼離不開縮進,縮進背后的思想是:

14、清楚地定義一個控制塊從哪里開始,到哪里結(jié)束。尤其是在你連續(xù)不斷的盯了20個小時的屏幕后,如果你有大尺寸的縮進。你將更容易發(fā)現(xiàn)縮進的好處。</p><p>  關(guān)于縮進主要有兩個爭論,一個是該用空格(Space)還是用制表符(Tab),另外一個是該用4格縮進還是8格縮進甚至都不是。建議總是使用Tab縮進,因為幾乎所有的代碼(不僅僅是C代碼)都在使用Tab縮進。</p><p>  現(xiàn)在,有些

15、人說8個字符大小的縮進導(dǎo)致代碼太偏右了,并且在一個80字符寬的終端屏幕上看著很不舒服。對這個問題的回答是:如果你有超過3個級別的縮進,你就有點犯糊涂了,應(yīng)當(dāng)修改你的程序。簡而言之,8個字符的縮進使程序更易讀,而且當(dāng)你把功能隱藏的太深時,多層次的縮進還會對此很直觀的給出警告。要留心這種警告信息。</p><p>  例外:對于由開發(fā)工具自動生成的代碼可以有不一致。</p><p><b

16、>  1.2 及時折行</b></p><p>  較長的語句(>80 字符)要分成多行書寫,長表達式要在低優(yōu)先級操作符處劃分新行,操作符放在新行之首,劃分出的新行要進行適當(dāng)?shù)目s進(至少1個TAB位置),使排版整齊,語句可讀。示例:</p><p>  report_or_not_flag = ((taskno < MAX_ACT_TASK_NUMBER)&l

17、t;/p><p>  && (n7stat_stat_item_valid (stat_item))</p><p>  && (act_task_table[taskno].result_data != 0));</p><p>  循環(huán)、判斷等語句中若有較長的表達式或語句,則要進行適應(yīng)的劃分,長表達式要在低優(yōu)先級操作符處劃分新行,操作

18、符放在新行之首。示例:</p><p>  if ((taskno < max_act_task_number)</p><p>  && (n7stat_stat_item_valid (stat_item)))</p><p><b>  {</b></p><p>  ... // progr

19、am code</p><p><b>  }</b></p><p>  for (i = 0, j = 0; (i < BufferKeyword[word_index].word_length)</p><p>  && (j < NewKeyword.word_length); i++, j++)</p

20、><p><b>  {</b></p><p>  ... // program code</p><p><b>  }</b></p><p>  for (i = 0, j = 0;</p><p>  (i < first_word_length) &&a

21、mp; (j < second_word_length);</p><p><b>  i++, j++)</b></p><p><b>  {</b></p><p>  ... // program code</p><p><b>  }</b></p>

22、;<p>  若函數(shù)或過程中的參數(shù)較長,則要進行適當(dāng)?shù)膭澐?。示例?lt;/p><p>  n7stat_str_compare((BYTE *) & stat_object,</p><p>  (BYTE *) & (act_task_table[taskno].stat_object),</p><p>  sizeof (_STAT

23、_OBJECT));</p><p>  n7stat_flash_act_duration( stat_item, frame_id *STAT_TASK_CHECK_NUMBER</p><p>  + index, stat_object );</p><p>  1.3 一行只寫一條語句</p><p>  不允許把多個短語句寫在一行

24、中,即一行只寫一條語句。示例,如下例子不符合規(guī)范:</p><p>  rect.length = 0; rect.width = 0;</p><p><b>  應(yīng)如下書寫</b></p><p>  rect.length = 0;</p><p>  rect.width = 0;</p>&l

25、t;p>  1.4 if、for、do、while等語句格式規(guī)定</p><p>  if 、for 、do 、while 、case 、switch 、default 等語句自占一行,且if 、for 、do 、while 等語句的執(zhí)行語句部分無論多少都要加花括號{}。</p><p><b>  1.5 空行</b></p><p>

26、  (1)變量說明之后必須加空行。</p><p>  (2)相對獨立的程序塊之間應(yīng)加空行。</p><p><b>  1.6 空格</b></p><p>  在兩個以上的關(guān)鍵字、變量、常量進行對等操作時,它們之間的操作符之前、之后或者前后要加空格;進行非對等操作時,如果是關(guān)系密切的立即操作符(如-> ),后不應(yīng)加空格。采用這種松散方

27、式編寫代碼的目的是使代碼更加清晰。</p><p>  由于留空格所產(chǎn)生的清晰性是相對的,所以,在已經(jīng)非常清晰的語句中沒有必要再留空格,如果語句已足夠清晰則括號內(nèi)側(cè)(即左括號后面和右括號前面)不需要加空格,多重括號間不必加空格,因為在C/C++語言中括號已經(jīng)是最清晰的標(biāo)志了。</p><p>  在長語句中,如果需要加的空格非常多,那么應(yīng)該保持整體清晰,而在局部不加空格。給操作符留空格時不

28、要連續(xù)留兩個以上空格。</p><p>  (1)逗號、分號只在后面加空格。</p><p>  int a, b, c;</p><p>  (2)比較操作符, 賦值操作符"="、 "+=",算術(shù)操作符"+"、"%",邏輯操作符"&&"、"

29、&",位域操作符"<<"、"^"等雙目操作符的前后加空格。</p><p>  if (current_time >= MAX_TIME_VALUE)</p><p><b>  {</b></p><p>  a = b + c;</p><p&g

30、t;<b>  }</b></p><p><b>  a *= 2;</b></p><p>  a = b ^ 2;</p><p>  (3)"!"、"~"、"++"、"--"、"&"(地址運算符)等單目操作符

31、前后不加空格。</p><p>  *p = 'a'; // 內(nèi)容操作"*"與內(nèi)容之間</p><p>  flag = !isEmpty; // 非操作"!"與內(nèi)容之間</p><p>  p = &mem; // 地址操作"&" 與內(nèi)容之間&l

32、t;/p><p>  i++; // "++","--"與內(nèi)容之間</p><p>  (4)"->"、"."前后不加空格。</p><p>  p->id = pid; // "->"指針前后不加空格</p>

33、<p>  (5) if、for、while、switch等與后面的括號間應(yīng)加空格,使if等關(guān)鍵字更為突出、明顯。</p><p>  if (a >= b && c > d)</p><p>  1.7 對變量的定義,盡量位于函數(shù)的開始位置</p><p>  (1)應(yīng)避免分散定義變量。</p><p&

34、gt;  (2)同一行內(nèi)不要定義過多變量。 </p><p>  (3)同一類的變量在同一行內(nèi)定義,或者在相鄰行定義。 </p><p>  (4)數(shù)組、指針等復(fù)雜類型的定義放在定義區(qū)的最后。 </p><p>  (5)變量定義區(qū)不做較復(fù)雜的變量賦值。</p><p>  1.8 程序各部分的放置順序</p><p>

35、;  在較小的項目中,按如下順序組織安排程序各部分:</p><p>  (1)#include <C的標(biāo)準(zhǔn)頭文件>。</p><p>  (2)#include 〞用戶自定義的文件〞。</p><p>  (3)#define 宏定義。</p><p>  (4)全局變量定義。</p><p>  (5)

36、函數(shù)原型聲明。</p><p>  (6)main函數(shù)定義。</p><p>  (7)用戶自定義函數(shù)。</p><p>  以上各部分之間、用戶自定義的函數(shù)之間應(yīng)加空行。注意,函數(shù)原型聲明統(tǒng)一集中放在main函數(shù)之前,不放在某個函數(shù)內(nèi)部。</p><p><b>  2 注釋</b></p><p&

37、gt;  2.1 注釋的原則和目的</p><p>  注釋的原則是有助于對程序的閱讀理解,在該加的地方都加了,注釋不宜太多也不能太少,注釋語言必須準(zhǔn)確、易懂、簡潔。通過對函數(shù)或過程、變量、結(jié)構(gòu)等正確的命名以及合理地組織代碼的結(jié)構(gòu),使代碼成為自注釋的——清晰準(zhǔn)確的函數(shù)、變量等的命名,可增加代碼可讀性,并減少不必要的注釋——過量的注釋則是有害的。</p><p>  注釋的目的是解釋代碼的目

38、的、功能和采用的方法,提供代碼以外的信息,幫助讀者理解代碼,防止沒必要的重復(fù)注釋信息。 示例:如下注釋意義不大。</p><p>  /* if receive_flag is TRUE */</p><p>  if (receive_flag)</p><p>  而如下的注釋則給出了額外有用的信息。</p><p>  /* if mt

39、p receive a message from links */</p><p>  if (receive_flag)</p><p>  2.2 函數(shù)頭部應(yīng)進行注釋</p><p>  函數(shù)頭部應(yīng)進行注釋,列出:函數(shù)的目的/ 功能、輸入?yún)?shù)、輸出參數(shù)、返回值、調(diào)用關(guān)系(函數(shù)、表)等。</p><p>  示例1:下面這段函數(shù)的注釋比較標(biāo)

40、準(zhǔn),當(dāng)然,并不局限于此格式,但上述信息建議要包含在內(nèi)。</p><p>  /*************************************************</p><p>  Function: // 函數(shù)名稱</p><p>  Description: // 函數(shù)功能、性能等的描述</p><p>

41、  Calls: // 被本函數(shù)調(diào)用的函數(shù)清單</p><p>  Called By: // 調(diào)用本函數(shù)的函數(shù)清單</p><p>  Input: // 輸入?yún)?shù)說明,包括每個參數(shù)的作</p><p>  // 用、取值說明及參數(shù)間關(guān)系。</p><p>  Output: /

42、/ 對輸出參數(shù)的說明。</p><p>  Return: // 函數(shù)返回值的說明</p><p>  Others: // 其它說明</p><p>  *************************************************/</p><p>  對于某些函數(shù),其部分參數(shù)為傳入值,

43、而部分參數(shù)為傳出值,所以對參數(shù)要詳細說明該參數(shù)是入口參數(shù),還是出口參數(shù),對于某些意義不明確的參數(shù)還要做詳細說明(例如:以角度作為參數(shù)時,要說明該角度參數(shù)是以弧度(PI),還是以度為單位),對既是入口又是出口的變量應(yīng)該在入口和出口處同時標(biāo)明。等等。</p><p>  在注釋中詳細注明函數(shù)的適當(dāng)調(diào)用方法,對于返回值的處理方法等。在注釋中要強調(diào)調(diào)用時的危險方面,可能出錯的地方。</p><p>

44、;  2.3 進行注釋時的注意事項</p><p>  (1)建議邊寫代碼邊注釋,修改代碼同時修改相應(yīng)的注釋,以保證注釋與代碼的一致性。不再有用的注釋要刪除。</p><p>  (2)注釋的內(nèi)容要清楚、明了,含義準(zhǔn)確,防止注釋二義性。說明:錯誤的注釋不但無益反而有害。</p><p>  (3)避免在注釋中使用縮寫,特別是非常用縮寫。在使用縮寫時或之前,應(yīng)對縮寫進

45、行必要的說明。</p><p>  (4)注釋應(yīng)與其描述的代碼相近,對代碼的注釋應(yīng)放在其上方或右方(對單條語句的注釋)相鄰位置,不可放在下面。除非必要,不應(yīng)在代碼或表達中間插入注釋,否則容易使代碼可理解性變差。</p><p>  示例:如下例子不符合規(guī)范。</p><p><b>  例1:</b></p><p> 

46、 /* get replicate sub system index and net indicator */</p><p>  repssn_ind = ssn_data[index].repssn_index;</p><p>  repssn_ni = ssn_data[index].ni;</p><p><b>  例2:</b>&

47、lt;/p><p>  repssn_ind = ssn_data[index].repssn_index;</p><p>  repssn_ni = ssn_data[index].ni;</p><p>  /* get replicate sub system index and net indicator */</p><p><

48、b>  應(yīng)如下書寫</b></p><p>  /* get replicate sub system index and net indicator */</p><p>  repssn_ind = ssn_data[index].repssn_index;</p><p>  repssn_ni = ssn_data[index].ni;&l

49、t;/p><p>  (5)對于所有有物理含義的變量、常量,如果其命名不是充分自注釋的,在聲明時都必須加以注釋,說明其物理含義。變量、常量、宏的注釋應(yīng)放在其上方相鄰位置或右方。</p><p><b>  示例:</b></p><p>  /* active statistic task number */</p><p>

50、;  #define MAX_ACT_TASK_NUMBER 1000</p><p>  #define MAX_ACT_TASK_NUMBER 1000 /* active statistic task number */</p><p>  (6)數(shù)據(jù)結(jié)構(gòu)聲明( 包括數(shù)組、結(jié)構(gòu)、類、枚舉等) ,如果其命名不是充分自注釋的,必須加以注釋。對數(shù)據(jù)結(jié)構(gòu)的注釋應(yīng)放在其上方相鄰位置,不可放在下

51、面;對結(jié)構(gòu)中的每個域的注釋放在此域的右方。</p><p>  示例:可按如下形式說明枚舉/數(shù)據(jù)/聯(lián)合結(jié)構(gòu)。</p><p>  /* sccp interface with sccp user primitive message name */</p><p>  enum SCCP_USER_PRIMITIVE</p><p><

52、b>  {</b></p><p>  N_UNITDATA_IND, /* sccp notify sccp user unit data come */</p><p>  N_NOTICE_IND, /* sccp notify user the No.7 network can not */</p><p>  /* transmiss

53、ion this message */</p><p>  N_UNITDATA_REQ, /* sccp user's unit data transmission request*/</p><p><b>  };</b></p><p>  (7)全局變量要有較詳細的注釋,包括對其功能、取值范圍、哪些函數(shù)或過程存取它以及存取時注

54、意事項等的說明。</p><p><b>  示例:</b></p><p>  /* The ErrorCode when SCCP translate */</p><p>  /* Global Title failure, as follows */ // 變量作用、含義</p><p>  /* 0

55、- SUCCESS 1 - GT Table error */</p><p>  /* 2 - GT error Others - no use */ // 變量取值范圍</p><p>  /* only function SCCPTranslate() in */</p><p>  /* this modual can modify

56、it, and other */</p><p>  /* module can visit it through call */</p><p>  /* the function GetGTTransErrorCode() */ // 使用方法</p><p>  BYTE g_GTTranErrorCode;</p><p>

57、;  (8)注釋與所描述內(nèi)容進行同樣的縮排,讓程序排版整齊,并方便注釋的閱讀與理解。</p><p>  示例:如下例子,排版不整齊,閱讀稍感不方便。</p><p>  void example_fun( void )</p><p><b>  {</b></p><p>  /* code one comments

58、 */</p><p>  CodeBlock One</p><p>  /* code two comments */</p><p>  CodeBlock Two</p><p><b>  }</b></p><p><b>  應(yīng)改為如下布局。</b></p

59、><p>  void example_fun( void )</p><p><b>  {</b></p><p>  /* code one comments */</p><p>  CodeBlock One</p><p>  /* code two comments */</p&g

60、t;<p>  CodeBlock Two</p><p><b>  }</b></p><p>  (9)將注釋與其上面的代碼用空行隔開。</p><p>  示例:如下例子,顯得代碼過于緊湊。</p><p>  /* code one comments */</p><p>

61、  program code one</p><p>  /* code two comments */</p><p>  program code two</p><p><b>  應(yīng)如下書寫</b></p><p>  /* code one comments */</p><p>  p

62、rogram code one</p><p>  /* code two comments */</p><p>  program code two</p><p>  (10)對變量的定義和分支語句(條件分支、循環(huán)語句等)必須編寫注釋。這些語句往往是程序?qū)崿F(xiàn)某一特定功能的關(guān)鍵,對于維護人員來說,良好的注釋幫助更好的理解程序,有時甚至優(yōu)于看設(shè)計文檔。</p

63、><p>  (11)對于switch 語句下的case 語句,如果因為特殊情況需要處理完一個case 后進入下一個case 處理(即上一個case后無break),必須在該case 語句處理完、下一個case 語句前加上明確的注釋,以清楚表達程序編寫者的意圖,有效防止無故遺漏break語句(可避免后期維護人員對此感到迷惑:原程序員是遺漏了break語句還是本來就不應(yīng)該有)。示例:</p><p&

64、gt;  case CMD_DOWN:</p><p>  ProcessDown();</p><p><b>  break;</b></p><p>  case CMD_FWD:</p><p>  ProcessFwd();</p><p><b>  if (...)<

65、/b></p><p><b>  {</b></p><p><b>  ...</b></p><p><b>  break;</b></p><p><b>  } else</b></p><p><b>

66、  {</b></p><p>  ProcessCFW_B(); // now jump into case CMD_A</p><p><b>  }</b></p><p>  case CMD_A:</p><p>  ProcessA();</p><p><b&g

67、t;  break;</b></p><p><b>  ...</b></p><p>  (12)在程序塊的結(jié)束行右方加注釋標(biāo)記,以表明某程序塊的結(jié)束。當(dāng)代碼段較長,特別是多重嵌套時,這樣做可以使代碼更清晰,更便于閱讀。示例:參見如下例子。</p><p><b>  if (...)</b></p&

68、gt;<p><b>  {</b></p><p>  program code</p><p>  while (index < MAX_INDEX)</p><p><b>  {</b></p><p>  program code</p><p>

69、;  } /* end of while (index < MAX_INDEX) */ // 指明該條while語句結(jié)束</p><p>  } /* end of if (...)*/ // 指明是哪條if語句結(jié)束</p><p>  (13)在順序執(zhí)行的程序中,每隔3—5行語句,應(yīng)當(dāng)加一個注釋,注明這一段語句所組成的小模塊的作用。對于自己的一些比較獨特的思想要求在注釋中標(biāo)明。&

70、lt;/p><p>  (14)注釋格式盡量統(tǒng)一,建議使用“/* …… */”。</p><p>  (15)注釋應(yīng)考慮程序易讀及外觀排版的因素,使用的語言若是中、英兼有的,建議多使用中文,除非能用非常流利準(zhǔn)確的英文表達——注釋語言不統(tǒng)一,影響程序易讀性和外觀排版,出于對維護人員的考慮,建議使用中文。</p><p><b>  3 命名規(guī)則</b>

71、;</p><p>  C是一門樸素的語言,你使用的命名也應(yīng)該這樣。與Modula-2和Pascal程序員不同,C程序員不使用諸如“ThisVariableIsATemporaryCounter”這樣“聰明”的名字。C程序員應(yīng)該叫它“tmp”,這寫起來更簡單,也不會更難懂。</p><p>  然而,當(dāng)面對復(fù)雜情況時就有些棘手,給全局變量取一個描述性的名字是必要的。把一個全局函數(shù)叫做“fo

72、o”是一種目光短淺的行為。全局函數(shù)也一樣,如果你有一個統(tǒng)計當(dāng)前用戶個數(shù)的函數(shù),應(yīng)當(dāng)把它命名為“count_active_user()”或者簡單點些的類似名稱,不應(yīng)該命名為“cntusr()”。</p><p>  3.1 三種流行的命名法則</p><p>  目前,業(yè)界共有四種命名法則:駝峰命名法、匈牙利命名法、帕斯卡命名法和下劃線命名法,其中前三種是較為流行的命名法。</p>

73、;<p>  (1)駝峰命令法。正如它的名稱所表示的那樣,是指混合使用大小寫字母來構(gòu)成變量和函數(shù)的名字。例如,下面是分別用駱駝式命名法和下劃線法命名的同一個函數(shù):</p><p>  printEmployeePaychecks();</p><p>  print_employee_paychecks();</p><p>  第一個函數(shù)名使用了駝峰

74、命名法,函數(shù)名中的每一個邏輯斷點都有一個大寫字母來標(biāo)記。第二個函數(shù)名使用了下劃線法,函數(shù)名中的每一個邏輯斷點都有一個下劃線來標(biāo)記。</p><p>  駝峰命名法近年來越來越流行了,在許多新的函數(shù)庫和Microsoft Windows這樣的環(huán)境中,它使用得當(dāng)相多。另一方面,下劃線法是C出現(xiàn)后開始流行起來的,在許多舊的程序和UNIX這樣的環(huán)境中,它的使用非常普遍。</p><p>  (2)

75、匈牙利命名法。廣泛應(yīng)用于象Microsoft Windows這樣的環(huán)境中。Windows 編程中用到的變量(還包括宏)的命名規(guī)則為匈牙利命名法,這種命名技術(shù)是由一位能干的 Microsoft 程序員查爾斯-西蒙尼(Charles Simonyi) 提出的。</p><p>  匈牙利命名法通過在變量名前面加上相應(yīng)的小寫字母的符號標(biāo)識作為前綴,標(biāo)識出變量的作用域、類型等。這些符號可以多個同時使用,順序是先m_(成員

76、變量)、再指針、再簡單數(shù)據(jù)類型、再其它。這樣做的好處在于能增加程序的可讀性,便于對程序的理解和維護。</p><p>  例如:m_lpszStr, 表示指向一個以0字符結(jié)尾的字符串的長指針成員變量。</p><p>  匈牙利命名法關(guān)鍵是:標(biāo)識符的名字以一個或者多個小寫字母開頭作為前綴;前綴之后的是首字母大寫的一個單詞或多個單詞組合,該單詞要指明變量的用途。</p><

77、;p>  (3)帕斯卡(pascal)命名法。與駝峰命名法類似,二者的區(qū)別在于:駝峰命名法是首字母小寫,而帕斯卡命名法是首字母大寫,如:</p><p>  DisplayInfo();</p><p>  string UserName;</p><p>  二者都是采用了帕斯卡命名法。</p><p>  (4)三種命名規(guī)則的小結(jié):

78、MyData就是一個帕斯卡命名的示例;myData是一個駝峰命名法,它第一個單詞的第一個字母小寫,后面的單詞首字母大寫,看起來像一個駱駝;iMyData是一個匈牙利命名法,它的小寫的i說明了它的型態(tài),后面的和帕斯卡命名相同,指示了該變量的用途。</p><p>  3.2 命名的基本原則</p><p>  (1)標(biāo)識符的命名要清晰、明了,有明確含義,同時使用完整的單詞或大家基本可以理解的

79、縮寫,避免使人產(chǎn)生誤解——盡量采用采用英文單詞或全部中文全拼表示,若出現(xiàn)英文單詞和中文混合定義時,使用連字符“_”將英文與中文割開。較短的單詞可通過去掉“元音”形成縮寫;較長的單詞可取單詞的頭幾個字母形成縮寫;一些單詞有大家公認的縮寫。例如:temp->tmp、flag->flg、statistic->stat、increment->inc、message->msg等縮寫能夠被大家基本認可。</p&g

80、t;<p>  (2)命名中若使用特殊約定或縮寫,則要有注釋說明。應(yīng)該在源文件的開始之處,對文件中所使用的縮寫或約定,特別是特殊的縮寫,進行必要的注釋說明。</p><p>  (3)自己特有的命名風(fēng)格,要自始至終保持一致,不可來回變化。個人的命名風(fēng)格,在符合所在項目組或產(chǎn)品組的命名規(guī)則的前提下,才可使用。(即命名規(guī)則中沒有規(guī)定到的地方才可有個人命名風(fēng)格)。</p><p>

81、  (4)對于變量命名,禁止取單個字符(如i 、j 、k... ),建議除了要有具體含義外,還能表明其變量類型、數(shù)據(jù)類型等,但i 、j 、k 作局部循環(huán)變量是允許的。變量,尤其是局部變量,如果用單個字符表示,很容易敲錯(如i寫成j),而編譯時又檢查不出來,有可能為了這個小小的錯誤而花費大量的查錯時間。</p><p>  (5)除非必要,不要用數(shù)字或較奇怪的字符來定義標(biāo)識符。</p><p&g

82、t;  (6)命名規(guī)范必須與所使用的系統(tǒng)風(fēng)格保持一致,并在同一項目中統(tǒng)一。</p><p>  (7)在同一軟件產(chǎn)品內(nèi),應(yīng)規(guī)劃好接口部分標(biāo)識符(變量、結(jié)構(gòu)、函數(shù)及常量)的命名,防止編譯、鏈接時產(chǎn)生沖突。對接口部分的標(biāo)識符應(yīng)該有更嚴(yán)格限制,防止沖突。如可規(guī)定接口部分的變量與常量之前加上“模塊”標(biāo)識等。</p><p>  (8)用正確的反義詞組命名具有互斥意義的變量或相反動作的函數(shù)等。下面是

83、一些在軟件中常用的反義詞組。</p><p>  add / remove begin / end create / destroy</p><p>  insert / delete first / last g et / release</p><p>  increment / decrement

84、 put / get</p><p>  add / delete lock / unlock open / close</p><p>  min / max old / new start / stop</p><p>  next / previous source /

85、 target show / hide</p><p>  send / receive source / destination</p><p>  cut / paste up / down</p><p><b>  示例:</b></p><p>  int min_sum

86、;</p><p>  int max_sum;</p><p>  int add_user( BYTE *user_name );</p><p>  int delete_user( BYTE *user_name );</p><p>  (9)除了編譯開關(guān)/ 頭文件等特殊應(yīng)用,應(yīng)避免使用_EXAMPLE_TEST_ 之類以下劃

87、線開始和結(jié)尾的定義。</p><p>  3.3 變量名的命名規(guī)則</p><p>  (1)變量的命名規(guī)則要求用“匈牙利法則”。即開頭字母用變量的類型,其余部分用變量的英文意思、英文的縮寫、中文全拼或中文全拼的縮寫,要求單詞的第一個字母應(yīng)大寫。</p><p>  即: 變量名=變量類型+變量的英文意思(或英文縮寫、中文全拼、中文全拼縮寫)</p>

88、<p>  對非通用的變量,在定義時加入注釋說明,變量定義盡量可能放在函數(shù)的開始處。</p><p><b>  見下表:</b></p><p>  bool 用b開頭 bFlg</p><p>  int 用i開頭 iCount</p><p>  short int 用n開頭 nStepCount<

89、/p><p>  long int 用l開頭 lSum</p><p>  char 用c開頭 cCount</p><p>  unsigned char 用by開頭</p><p>  float 用f開頭 fAvg</p><p>  double 用d開頭 dDeta</p><p>  

90、unsigned int(WORD) 用w開頭 wCount</p><p>  unsigned long int(DWORD) 用dw開頭 dwBroad</p><p>  字符串 用s開頭 sFileName</p><p>  用0結(jié)尾的字符串 用sz開頭 szFileName</p><p>  (2)指針變量命名的基本原則為:&

91、lt;/p><p>  對一重指針變量的基本原則為:“p”+變量類型前綴+命名,如一個float*型應(yīng)該表示為pfStat。對二重指針變量的基本規(guī)則為:“pp”+變量類型前綴+命名。對三重指針變量的基本規(guī)則為:“ppp”+變量類型前綴+命名。</p><p>  (3)全局變量用g_開頭,如一個全局的長型變量定義為g_lFailCount,即:變量名=g_+變量類型+變量的英文意思(或縮寫)。

92、此規(guī)則還可避免局部變量和全局變量同名而引起的問題。</p><p>  (4)靜態(tài)變量用s_開頭,如一個靜態(tài)的指針變量定義為s_plPerv_Inst,即: 變量名=s_+變量類型+變量的英文意思(或縮寫)</p><p>  (5)對枚舉類型(enum)中的變量,要求用枚舉變量或其縮寫做前綴。并且要求用大寫。如:</p><p>  enum cmEMDAYS&l

93、t;/p><p><b>  {</b></p><p>  EMDAYS_MONDAY;</p><p>  EMDAYS_TUESDAY;</p><p><b>  ……</b></p><p><b>  };</b></p><

94、p>  (6)對struct、union變量的命名要求定義的類型用大寫。并要加上前綴,其內(nèi)部變量的命名規(guī)則與變量命名規(guī)則一致。</p><p>  結(jié)構(gòu)一般用S開頭,如:</p><p>  struct ScmNPoint</p><p><b>  {</b></p><p>  int nX;//點的X位置&

95、lt;/p><p>  int nY; //點的Y位置</p><p><b>  };</b></p><p>  聯(lián)合體一般用U開頭,如:</p><p>  union UcmLPoint</p><p><b>  {</b></p><p>&l

96、t;b>  LONG lX;</b></p><p><b>  LONG lY;</b></p><p><b>  }</b></p><p>  (7)對常量(包括錯誤的編碼)命名,要求常量名用大寫,常量名用英文表達其意思。當(dāng)需要由多個單詞表示時,單詞與單詞之間必須采用連字符“_”連接。</p

97、><p>  如:#define CM_FILE_NOT_FOUND CMMAKEHR(0X20B) 其中CM表示類別。</p><p>  (8)對const 的變量要求在變量的命名規(guī)則前加入c_,即:c_+變量命名規(guī)則;示例:</p><p>  const char* c_szFileName;</p><p>  3.4 函數(shù)的命名規(guī)范&

98、lt;/p><p>  (1)函數(shù)的命名應(yīng)該盡量用英文(或英文縮寫、中文全拼、中文全拼縮寫)表達出函數(shù)完成的功能——函數(shù)名應(yīng)準(zhǔn)確描述函數(shù)的功能。遵循動賓結(jié)構(gòu)的命名法則,函數(shù)名中動詞在前,并在命名前加入函數(shù)的前綴,函數(shù)名的長度不得少于8個字母。函數(shù)名首字大寫,若包含有兩個單詞的每個單詞首字母大寫。如果是OOP 方法,可以只有動詞(名詞是對象本身)。示例:</p><p>  LONG GetDe

99、viceCount(……);</p><p>  void print_record( unsigned int rec_ind ) ;</p><p>  int input_record( void ) ;</p><p>  unsigned char get_current_color( void ) ;</p><p>  (2)

100、避免使用無意義或含義不清的動詞為函數(shù)命名。如使用process、handle等為函數(shù)命名,因為這些動詞并沒有說明要具體做什么。</p><p>  (3)必須使用函數(shù)原型聲明。函數(shù)原型聲明包括:引用外來函數(shù)及內(nèi)部函數(shù),外部引用必須在右側(cè)注明函數(shù)來源: 模塊名及文件名;內(nèi)部函數(shù),只要注釋其定義文件名——和調(diào)用者在同一文件中(簡單程序)時不需要注釋。</p><p>  應(yīng)確保每個函數(shù)聲明中的

101、參數(shù)的名稱、類型和定義中的名稱、類型一致。</p><p>  3.5 函數(shù)參數(shù)命名規(guī)范</p><p>  (1)參數(shù)名稱的命名參照變量命名規(guī)范。</p><p>  (2)為了提高程序的運行效率,減少參數(shù)占用的堆棧,傳遞大結(jié)構(gòu)的參數(shù),一律采用指針或引用方式傳遞。</p><p>  (3)為了便于其他程序員識別某個指針參數(shù)是入口參數(shù)還是出

102、口參數(shù),同時便于編譯器檢查錯誤,應(yīng)該在入口參數(shù)前加入const標(biāo)志。如:</p><p>  ……cmCopyString(const CHAR * c_szSource, CHAR * szDest)</p><p>  3.6 文件名(包括動態(tài)庫、組件、控件、工程文件等)的命名規(guī)范</p><p>  文件名的命名要求表達出文件的內(nèi)容,要求文件名的長度不得少于5

103、個字母,嚴(yán)禁使用象file1,myfile之類的文件名。</p><p><b>  4 可讀性</b></p><p>  4.1 避免使用默認的運算優(yōu)先級</p><p>  注意運算符的優(yōu)先級,并用括號明確表達式的操作順序,避免使用默認優(yōu)先級,可防止閱讀程序時產(chǎn)生誤解,防止因默認的優(yōu)先級與設(shè)計思想不符而導(dǎo)致程序出錯。</p>

104、<p>  示例:下列語句中的表達式</p><p>  word = (high << 8) | low (1)</p><p>  if ((a | b) && (a & c)) (2)</p><p>  if ((a | b) < (c & d)) (3)</p

105、><p><b>  如果書寫為:</b></p><p>  high << 8 | low</p><p>  a | b && a & c</p><p>  a | b < c & d</p><p><b>  由于</b&g

106、t;</p><p>  high << 8 | low = ( high << 8) | low,</p><p>  a | b && a & c = (a | b) && (a & c),</p><p>  (1)(2)不會出錯,但語句不易理解;</p><p>

107、  a | b < c & d = a | (b < c) & d,(3)造成了判斷條件出錯。</p><p>  4.2 使用有意義的標(biāo)識,避免直接使用數(shù)字</p><p>  避免使用不易理解的數(shù)字,用有意義的標(biāo)識來替代。涉及物理狀態(tài)或者含有物理意義的常量,不應(yīng)直接使用數(shù)字,必須用有意義的枚舉或宏來代替。</p><p>  示例:如

108、下的程序可讀性差。</p><p>  if (Trunk[index].trunk_state == 0)</p><p><b>  {</b></p><p>  Trunk[index].trunk_state = 1;</p><p>  ... // program code</p><

109、p><b>  }</b></p><p><b>  應(yīng)改為如下形式。</b></p><p>  #define TRUNK_IDLE 0</p><p>  #define TRUNK_BUSY 1</p><p>  if (Trunk[index].trunk_state == TR

110、UNK_IDLE)</p><p><b>  {</b></p><p>  Trunk[index].trunk_state = TRUNK_BUSY;</p><p>  ... // program code</p><p><b>  }</b></p><p>

111、  4.3 源程序中關(guān)系較為緊密的代碼應(yīng)盡可能相鄰</p><p>  這樣做的好處是便于程序閱讀和查找。示例:以下代碼布局不太合理。</p><p>  rect.length = 10;</p><p>  char_poi = str;</p><p>  rect.width = 5;</p><p>  若按

112、如下形式書寫,可能更清晰一些。</p><p>  rect.length = 10;</p><p>  rect.width = 5; // 矩形的長與寬關(guān)系較密切,放在一起。</p><p>  char_poi = str;</p><p>  4.4 不要使用難懂的技巧性很高的語句、復(fù)雜的表達式</p><p&g

113、t;  除非很有必要時,原則上不要使用難懂的技巧性很高的語句和復(fù)雜的表達式——高技巧語句不等于高效率的程序,源程序占用空間的節(jié)約并不等于目標(biāo)程序占用空間的節(jié)約,實際上程序的效率關(guān)鍵在于算法。</p><p>  (1)如下表達式,考慮不周就可能出問題,也較難理解。</p><p>  * stat_poi ++ += 1;</p><p>  * ++ stat_p

114、oi += 1;</p><p><b>  應(yīng)分別改為如下:</b></p><p>  *stat_poi += 1;</p><p>  stat_poi++; // 此二語句功能相當(dāng)于“ * stat_poi ++ += 1; ”</p><p>  ++ stat_poi;</p><

115、;p>  *stat_poi += 1; // 此二語句功能相當(dāng)于“ * ++ stat_poi += 1; ”</p><p>  (2)如下表達式,不同的編譯器給出的結(jié)果不一樣,b[i]是否先執(zhí)行?</p><p>  x=b[i] + i++;</p><p><b>  應(yīng)改為:</b></p><p> 

116、 x = b[i] + i;</p><p><b>  i++;</b></p><p><b>  5 變量與結(jié)構(gòu)</b></p><p>  5.1 謹(jǐn)慎使用全局(公共)變量</p><p>  (1)去掉沒必要的公共變量。公共變量是增大模塊間耦合的原因之一,故應(yīng)減少沒必要的公共變量以降低模塊

117、間的耦合度。</p><p>  (2)仔細定義并明確公共變量的含義、作用、取值范圍及公共變量間的關(guān)系。在對變量聲明的同時,應(yīng)對其含義、作用及取值范圍進行注釋說明,同時若有必要還應(yīng)說明與其它變量的關(guān)系。</p><p>  (3)防止局部變量與公共變量同名——通過使用較好的命名規(guī)則來消除此問題。</p><p>  5.2 數(shù)據(jù)類型間的轉(zhuǎn)換</p>&

118、lt;p>  (1)編程時,要注意數(shù)據(jù)類型的強制轉(zhuǎn)換。當(dāng)進行數(shù)據(jù)類型強制轉(zhuǎn)換時,其數(shù)據(jù)的意義、轉(zhuǎn)換后的取值等都有可能發(fā)生變化,而這些細節(jié)若考慮不周,就很有可能留下隱患。</p><p>  (2)對編譯系統(tǒng)默認的數(shù)據(jù)類型轉(zhuǎn)換,也要有充分的認識。示例:如下賦值,多數(shù)編譯器不產(chǎn)生告警,但值的含義還是稍有變化。</p><p><b>  char chr;</b>&

119、lt;/p><p>  unsigned short int exam;</p><p><b>  chr = -1;</b></p><p>  exam = chr; // 編譯器不產(chǎn)生告警,此時exam為0xFFFF。</p><p>  (3)盡量減少沒有必要的數(shù)據(jù)類型默認轉(zhuǎn)換與強制轉(zhuǎn)換。例如,所有的 unsign

120、ed類型都應(yīng)該有后綴“U”以明確其類型。</p><p>  (4)合理地設(shè)計數(shù)據(jù)并使用自定義數(shù)據(jù)類型,避免數(shù)據(jù)間進行不必要的類型轉(zhuǎn)換。</p><p>  (5)對自定義數(shù)據(jù)類型進行恰當(dāng)命名,使它成為自描述性的,以提高代碼可讀性。注意其命名方式在同一產(chǎn)品中的統(tǒng)一,并且保證沒有多重定義。使用自定義類型,可以彌補編程語言提供類型少、信息量不足的缺點,并能使程序清晰、簡潔。示例:可參考如下方式

121、聲明自定義數(shù)據(jù)類型。</p><p>  下面的聲明可使數(shù)據(jù)類型的使用簡潔、明了。</p><p>  typedef unsigned char BYTE;</p><p>  typedef unsigned short WORD;</p><p>  typedef unsigned int DWORD;</p>&

122、lt;p>  下面的聲明可使數(shù)據(jù)類型具有更豐富的含義。</p><p>  typedef float DISTANCE;</p><p>  typedef float SCORE;</p><p>  (6)不要用八進制數(shù)——整型常數(shù)以”0“開始會被認為是8進制。示例:</p><p>  code[1]=109</p>

123、<p>  code[2]=100</p><p>  code[3]=052</p><p>  code[4]=071</p><p>  如果是對總線消息初始化,會有危險。</p><p><b>  6 函數(shù)與過程</b></p><p>  6.1 函數(shù)的功能與規(guī)模設(shè)計&l

124、t;/p><p>  (1)函數(shù)應(yīng)當(dāng)短而精美,而且只做一件事。不要設(shè)計多用途面面俱到的函數(shù),多功能集于一身的函數(shù),很可能使函數(shù)的理解、測試、維護等變得困難。 一個函數(shù)應(yīng)最多占滿1或2個屏幕(就象我們知道的那樣,ISO/ANSI的屏幕大小是80X24),只做一件事并且把它做好。</p><p>  一個函數(shù)的最大長度與它的復(fù)雜度和縮進級別成反比。所以,如果如果你有一個概念上簡單(案,“簡單”是s

125、imple而不是easy)的函數(shù),它恰恰包含著一個很長的case語句,這樣你不得不為不同的情況準(zhǔn)備不懂的處理,那么這樣的長函數(shù)是沒問題的。</p><p>  然而,如果你有一個復(fù)雜的函數(shù),你猜想一個并非天才的高一學(xué)生可能看不懂得這個函數(shù),你就應(yīng)當(dāng)努力把它減縮得更接近前面提到的最大函數(shù)長度限制??梢允褂靡恍┹o助函數(shù),給它們?nèi)∶枋鲂缘拿?如果你認為這些輔助函數(shù)的調(diào)用是性能關(guān)鍵的,可以讓編譯器把它們內(nèi)聯(lián)進來,這比在

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論