程式設計修養(六) (轉)

amyz發表於2007-08-14
程式設計修養(六) (轉)[@more@]

23、static的使用
————————
static關鍵字,表示了“靜態”,一般來說,他會被經常用於變數和。一個static的變數,其實就是全域性變數,只不過他是有作用域的全域性變數。比如一個函式中的static變數:

char*
getConsumerName()
{
  static int cnt = 0;
 
  ....
  cnt++;
  ....
}

cnt變數的值會跟隨著函式的次而遞增,函式退出後,cnt的值還存在,只是cnt只能在函式中才能被訪問。而cnt的也只會在函式第一次被呼叫時才會被分配和初始化,以後每次進入函式,都不為static分配了,而直接使用上一次的值。

對於一些被經常呼叫的函式內的常量,最好也宣告成static(參見第12條)

但static的最多的用處卻不在這裡,其最大的作用的控制訪問,在C中如果一個函式或是一個全域性變數被宣告為static,那麼,這個函式和這個全域性變數,將只能在這個C中被訪問,如果別的C檔案中呼叫這個C檔案中的函式,或是使用其中的全域性(用extern關鍵字),將會發生連結時錯誤。這個特性可以用於資料和保密。

 

24、函式中的程式碼尺寸
——————————
一個函式完成一個具體的功能,一般來說,一個函式中的程式碼最好不要超過600行左右,越少越好,最好的函式一般在100行以內,300行左右的孫函式就差不多了。有證據表明,一個函式中的程式碼如果超過500行,就會有和別的函式相同或是相近的程式碼,也就是說,就可以再寫另一個函式。

另外,函式一般是完成一個特定的功能,千萬忌諱在一個函式中做許多件不同的事。函式的功能越單一越好,一方面有利於函式的易讀性,另一方面更有利於程式碼的維護和重用,功能越單一表示這個函式就越可能給更多的程式提供服務,也就是說共性就越多。

雖然函式的呼叫會有一定的開銷,但比起後期維護來說,增加一些執行時的開銷而換來更好的可維護性和程式碼重用性,是很值得的一件事。


25、typedef的使用
—————————

typedef是一個給型別起別名的關鍵字。不要小看了它,它對於你程式碼的維護會有很好的作用。比如C中沒有bool,於是在一個軟體中,一些程式設計師使用int,一些程式設計師使用short,會比較混亂,最好就是用一個typedef來定義,如:

  typedef char bool;
 
一般來說,一個C的工程中一定要做一些這方面的工作,因為你會涉及到跨平臺,不同的平臺會有不同的字長,所以利用預編譯和typedef可以讓你最有效的維護你的程式碼,如下所示:

  #ifdef 2_5
  typedef boolean_t  BOOL_T;
  #else
  typedef int BOOL_T;
  #endif
 
  typedef short  INT16_T;
  typedef unsigned short  UINT16_T;
  typedef int  INT32_T;
  typedef unsigned int UINT32_T;
 
  #ifdef
  typedef _int64  INT64_T;
  #else
  typedef long long  INT64_T;
  #endif
 
  typedef float FLOAT32_T;
  typedef char*  STRING_T;
  typedef unsigned char  BYTE_T;
  typedef time_t  TIME_T;
  typedef INT32_T  PID_T;
 
使用typedef的其它規範是,在結構和函式指標時,也最好用typedef,這也有利於程式的易讀和可維護性。如:

  typedef struct _hostinfo {
  HOSTID_T  host;
  INT32_T  hostId;
  STRING_T  hostType;
  STRING_T  hostModel;
  FLOAT32_T  Factor;
  INT32_T  numCPUs;
  INT32_T  nDisks;
  INT32_T  memory;
  INT32_T  s;
  } HostInfo;


  typedef INT32_T (*RsrcReqHandler)(
   void *info,
   JobArray *jobs,
   AllocInfo *allocInfo,
   AllocList *allocList);

C++中這樣也是很讓人易讀的:

  typedef CArray HostInfoArray;

於是,當我們用其定義變數時,會顯得十分易讀。如:

  HostInfo* phinfo;
  RsrcReqHandler* pRsrcHand;

這種方式的易讀性,在函式的引數中十分明顯。

關鍵是在程式種使用typedef後,幾乎所有的程式中的型別宣告都顯得那麼簡潔和清淅,而且易於維護,這才是typedef的關鍵。

 

26、為常量宣告宏
————————
最好不要在程式中出現數字式的“硬編碼”,如:

  int user[120];
 
為這個120宣告一個宏吧。為所有出現在程式中的這樣的常量都宣告一個宏吧。比如TimeOut的時間,最大的數量,還有其它,只要是常量就應該宣告成宏。如果,突然在程式中出現下面一段程式碼,

  for ( i=0; i<120; i++){
  ....
  }

120是什麼?為什麼會是120?這種“硬編碼”不僅讓程式很讀,而且也讓程式很不好維護,如果要改變這個數字,得同時對所有程式中這個120都要做修改,這對修改程式的人來說是一個很大的痛苦。所以還是把常量宣告成宏,這樣,一改百改,而且也很利於程式閱讀。

  #define MAX_USR_CNT 120
 
  for ( i=0; i  ....
  }

這樣就很容易瞭解這段程式的意圖了。

有的程式設計師喜歡為這種變數宣告全域性變數,其實,全域性變數應該儘量的少用,全域性變數不利於封裝,也不利於維護,而且對程式空間有一定的開銷,一不小心就造成換頁,造成程式執行速度等問題。所以宣告成宏,即可以免去全域性變數的開銷,也會有速度上的優勢。


27、不要為宏定義加分號
———————————

有許多程式設計師不知道在宏定義時是否要加分號,有時,他們以為宏是一條語句,應該要加分號,這就錯了。當你知道了宏的原理,你會贊同我為會麼不要為宏定義加分號的。看一個例子:

  #define MAXNUM 1024;

這是一個有分號的宏,如果我們這樣使用:

  half = MAXNUM/2;
 
  if ( num < MAXNUM )

等等,都會造成程式的編譯錯誤,因為,當宏展開後,他會是這個樣子的:

  half = 1024;/2;
 
  if ( num < 1024; )
 
是的,分號也被展進去了,所以造成了程式的錯誤。請相信我,有時候,一個分號會讓你的程式出現成百個錯誤。所以還是不要為宏加最後一個分號,哪怕是這樣:

  #define LINE  "================================="
 
  #define PRINT_LINE  printf(LINE)

  #define PRINT_NLINE(n)  while ( n-- >0 ) { PRINT_LINE; }
 
都不要在最後加上分號,當我們在程式中使用時,為之加上分號,

  main()
  {
  char *p = LINE;
  PRINT_LINE;
  }

這一點非常符合習慣,而且,如果忘加了分號,給出的錯誤提示,也會讓我們很容易看懂的。

/Develop/read_article.?id=18273"> 

(版權所有,轉載時請註明出處和作者資訊)


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

相關文章