程式碼的風格 (轉)

worldblog發表於2007-12-05
程式碼的風格 (轉)[@more@]

 

 

Code Style:namespace prefix = o ns = "urn:schemas--com::office" />

程式碼的風格

 

1.  簡介

2.  什麼是風格?

3.  程式碼的風格為什麼如此重要?

4.  更少的工作,更多的文件?

5.  推薦的程式碼風格

6.  簡單的文件

7.  輸出風格

8.  結論

 

簡介

讓我們面對一下吧…如果您是一個資深的員,那麼您總是在最後期限下工作並且您的最終目標是完成您設計的。如果您是個新手,您的努力是更多的研究、試驗、當然還有錯誤和一心希望您的程式可以象打算的那樣執行。不管怎樣,當您的程式真的如願以償的執行時那種成功的感覺令人十分振奮,但更多的程式設計師發現能夠用良好的風格生成程式內部程式碼時的那種自豪的感覺更棒。

如果您是小組的成員或者如果您還在書寫學校分配的任務,那麼您會有機會被要求遵守某些必須遵守的風格規則。 絕大多數的程式設計師考慮風格這件事就象一個10歲大的孩子看待就寢時間一樣。但資深程式設計師和我所見過的小組領導及多年來使用許多風格的程式設計師都會試圖向您傳達良好的程式碼風格與您所得意的一些書寫程式碼的技巧同樣重要。在這篇文章中我將嘗試包括一些輸出風格的觀點,這也許有助您的旅程。

 


更少的工作,更多的文件?

因此風格意味著要在程式碼的每一行加上註解,對嗎?錯。如果沒有做對的話,註解也會變成一場災難。 我仍然希望一個程式設計師學會喜歡輸入註解或真正對註解有足夠的重視。為了未來的可維護性必須強制自己正確的放置註解。所以怎麼能夠不使用註解?

顯然對一個新手最困難的事是懂得什麼是好的變數命名。讓我們看看以下的程式碼。您能告訴我下面的程式碼是做什麼的嗎?

  float __fastcall TExampleForm::CalcAverageGrade(void)


  {


  int y=0;


  int i=0;


  for (i; i<x; i++) {


  y=y+g[i]; 


  }


  return float(y/x);


  }


 在上面的例子中,您能很輕易的告訴我y代表什麼呢?x又是什麼呢?這段程式碼也許需要一些註釋來解釋這些變數的代表意義及程式碼中發生了什麼?應用以上的程式碼風格,看不出什麼邏輯關係。現在讓我們看看應用更好的程式碼風格以後,程式碼是何等模樣?

  float __fastcall TExampleForm::CalcAverageGrade(void)


  {


  int total=0;


  for (int i=0; i<maxGrades; i++)


  {


  total+=Grades[i];


  } //求所有成績的和


 


  return float(total/maxGrades);


  } //計算平均成績


在您除錯時以上兩段程式碼孰優孰劣,已不必多說。現在就讓我們討論一些能夠讓您的程式碼更具有可維護性的推薦風格吧。


推薦的程式碼風格

1.  使用有描述意義的變數名。

2.  使用i, j, k, l, m作為迴圈計數變數。這起源於Fortran,自始自終這都是事實上的工業標準。

3.  在閉合括號處為所有的宣告和方法註釋。這樣在嘗試找到與此配對的上一個初始括號時更容易做決定,尤其在宣告很長時。

4.  考慮將if後面或迴圈定義體的初始括號放在一個單獨的行上。這真的有助於您找到與其對應的閉合括號。

5.  使用適當的組合運算子 (+=, *=, 等等)。對自增(自減)變數使用++ 和 -–運算子。正確使用這些運算子會使您的程式碼更可讀和更一致。這也減少了輸入的字元數量。組合運算子也會幫助生成更快的程式碼。舉例來說,i++產生的asm()程式碼是inc [i],而i=i+1將會產生如下的asm(彙編)程式碼mov eax,[i] inc eax mov [i],eax。

6.  註解程式碼時,要明智些!如果一段程式碼的邏輯關係很複雜,註解將有助於別人理解程式碼的意圖。但如果邏輯關係直線向前,避免加上並非必須的註解。要象維護您的程式碼一樣維護您的註解!

7.  命名變數時,使用有描述意義的大寫。簡單變數(例如,int, long, String)應該以小寫字元開始。複雜變數(例如,、結構、陣列)應該以大寫開始。變數名稱中包含的所有單詞都應該大寫開頭。這會讓讀(寫)程式碼的人對所訪問的資料型別有一個清晰的第一印象。

8.  避免在變數名中使用下劃線。絕大多數的編譯器中,它都有特殊的意義。

9.  儘可能(而不是瘋狂的)將程式碼模組化。合理的話,將程式碼放入中去。這允許更好的程式碼重用性和可讀性。

10. 使用正確的迴圈。如果程式碼最少要一次,使用do-while迴圈,否則使用while-do迴圈。如果確切的迴圈執行次數已知,使用for迴圈。

11. 在事件發生的數量超過兩種時,只要可能就使用switch宣告。同時,無論何時只要可能就包含一個switch default(預設開關),這樣總會有一個選項被觸發。Switch宣告很容易除錯,而且比組合的多重if宣告執行速度更快。

12. 在您程式碼中的邏輯步驟之間加上一個空行(例如,定義變數、迴圈、等等)。

13. 宣告變數的位置非常重要。變數應該宣告的位置幾乎沒有隨意性。當變數用於整個(類)物件或者必須在物件外可見的時候,變數應放在頭中。臨時變數如果不需要在if宣告或迴圈體外被訪問的話,就應在它們內部宣告。不正確的放置變數宣告會導致執行速度減慢、錯誤、或者引起誤導的程式碼。

14. 初始化所有的變數。

15. 如果您有非空返回(帶返回值)的函式,確保所有的退出點都使用了return。對編譯器產生的警告"function should return a value"(函式應該返回一個值)要引起足夠重視。這是嚴重警告並且可能導致您的軟體發生隨機錯誤。

16. 在兩個不同型別的變數間賦值時,應對變數進行強制轉換計算來避免編譯器的警告(例如:int x; float y; … y=float x;)。這麼做可以防止"Conversion may loose significant digits"的警告。作為一個程式設計師您的目標應該儘可能的減少警告的數量。而強制型別轉換將消除其中的大多數。

17. 永遠在刪除後將指標設為NULL。

18. 儘量仔細的調查以避免“閉門造舊車”。經過證明的函式與程式使用時優先於新寫的程式碼。這會讓您有更多的時間去寫真實的邏輯程式碼並且非常有助於維護。儘管儘管動態連結串列的書寫非常有趣,它早已被完成了!

19. 正確的拼寫很重要。如果拼寫有錯的話,將來的搜尋會很困難。

20. 永遠不要使用兩個只有大小寫不同的變數名字。

21. 在您建立程式碼時就輸入註解,而不是以後。在您修改程式碼的時候,保持對註解的維護。

22. 如果您在或除錯時註解(rem)了一段程式碼的話,確保您最後將被註解的程式碼刪除。

23. 最後最重要的是…保持風格的一致。

 

 簡單的文件

 平凡的文件在建立一個可維護的是卻十分有效。您應該設定一個標準來為您的文件註解模板規定檔案的開始處應該放置的內容。這裡是某些應該在您的模板中完成的東西:

1.  原創作者名字

2.  原始建立日期

3.  檔案的用途

4.  包括使用指導在內的主要內容列表

5.  包括修訂日期的修訂歷史記錄。同時應該說明修訂時發現並修復的。

檔案註解應該放在文件頭部,並儘量簡明。下面是我們現在的應用程式的一個例子。這個例子比較複雜。

/*

Written by(作者): tt Cross   

Date originally Completed(原始完成日期): 9/18/99

Purpose(用途): Main routine for NY Billing. This logic calculates the installments and provs all data necessary to print, display, and report billing status. The fowill display the billing information. The main structure, InvoiceInfo, has all information including detail of Installments and Payment activities. Although the main is a form, the form need not be shown in order to get billing information. This is the only billing logic for this version of the system. All billing inquiries should go through this routine.

Usage(用法): Nothing will be performed during the OnCreate event with the exception of setting some reference variables. All calculations are done by calling the main routine LoadAcctInfo. This routine can be called many times for different policies since it is fully initialized on each call. There are 5 parameters for the main functions and their usage is as follows:

bool LoadAcctInfo( 

  String policyNo - Supplies the logic with the targeted PolicyNo.  
  bool printInvoice - Set to true if you want to print the invoice.  
  bool nightRunning - If being called from the night, set to true.  
  bool payableRunning - If being called by accounting rpt, set to true.  
  String masterPrintDate - This is a date. For more info on usage, see cpp. 
  );

No preliminary logic needs to be performed and the function will return true in most cases. No structures are passed since the main structure is public. It is imperative that the LoadAcctInfo be called prior to displaying the screen or unexpected results can occur since the main structures will not be initialized.

struct InvoiceInfoStruct{  
  PaymentHistoryStruct Payments[30]; - Payment History  
  int paymentCount; - Count of Payments 
  InstallmentStruct Installments[30]; - Installment Information  
  int installmentCount; - Count of Installments 
  int currInstall; - The current due installment 
  float totalPaid; - The total paid on file * 
  float totalDue; - Total due on file 
  float pastDue; - Total amount past due 
  float totalBilled; - Total amount billed on file 
  float totalApplied; - Amount applied to installments **  
  String equityDate; - The date the premium is paid to  
  String dateDue; - Date the file is due a payment 

  float annualizedPremium; - the annualized premium ***  
  };

* Restricted to masterPrintDate
** Should equal total paid
*** What the annualized premium is for the policy as stored in the tables if rated for one year.

Update History(歷史):
09/18/1999 - Scott - Completed
02/01/2000 – Scott - Fixed totalPaid error on cancelled file
*/

 輸出風格

輸出風格沒有標準。在我的觀念中,程式設計最精彩的部分是程式的設計。您可以有自己的選擇,從什麼是好的或壞的直到系統的外觀和感覺。儘管如此,仍有些有助於您的設計的建議。

1.  選擇統一的字型。

2.  把介面設計成可以在不同解析度和不同設定下正常工作。啟用/不用大字型,然後測試您的軟體。並假定仍在的VGA設定下執行(640X480 16色)。

3.  在多種顏色方案下測試軟體。

4.  嘗試維護逼真的3D效果。大多數情況下,初始的form(頁面)應該是凸起的並帶有一種附加的下凹效果。儘管這看起來有點小兒科,但這使得程式有了深度並非常有助於分割頁面。

5.  牢記輸出效果的。在集中的迴圈中,更新越簡單,執行就越快。

6.  儘量避免在介面中使用太多的噱頭和效果。這會給人不專業的感覺,也可能傷害使用者的信心,除非工程要求浮華的設計。

7.  設計登入螢幕,讓使用者無須滑鼠動作就可以獲得更多。

8.  您的使用者也許欣賞毫不雜亂的環境,但也要牢記這依靠使用者的,多屏可能會使系統太慢。嘗試在速度和可用性之間找到平衡吧。

9.  在任何時候使用彈出提示和提示條都是合適的。從一開始就就記住要將頁面設定成這樣的。

10.  嚮導型別的介面對複雜的多步驟過程時十分合適。這使得軟體可以指導使用者一步步的走過這些步驟。找一個好的NoteBook(筆記本)元件吧。

11.  在進行長時間的操作時,應該總是Application->ProcessMessages();保持介面更新並讓windows知道您的應用程式仍然處於活動狀態且能夠響應訊息。

12.  最後最重要的是…保持系統風格的一致。


 

結論

程式設計的風格要比許多程式設計師想像的更重要的多。您想讓別的程式設計師看見您現在的工程中的程式碼嗎?您是不是對您的程式碼和您的系統一樣自豪呢?現在花點時間來決定想在您的程式碼中採用何種風格並開始每天使用這種風格。記住,用6個星期來發展一個習慣,不管它是好的還是壞的。

祝 好運!

 

原著:  Scott Cross

翻譯: cker


 

版權說明

國內的網站上,有許多關於C++Builder的內容,但多以軟體、元件為主。論壇裡也大都不能令人滿意,很空虛的感覺。書籍又都昂貴,內容卻有搶錢之嫌。對銀子不足的初學者、自學者關愛不夠,因而想盡自己的綿薄之力。

文中的所有資料都是從國外網站上收集而來。因為E文不方便,所以翻成中文。又因為English和都不是非常好,文中的錯誤在所難免。若大家覺得有用的話,我計劃不斷蒐集翻譯一些有用的東西。

有任何意見和建議請tocker@sina.com

您可以隨意複製、分發、此文件。但未經本人同意,您不可以擷取、改動本文片斷,或用本文謀取任何形式的利益。

 

史平洋

2001.2


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988617/,如需轉載,請註明出處,否則將追究法律責任。

相關文章