程式設計修養(四)

2021-07-09 10:48:08 字數 3717 閱讀 9109

11、出錯資訊的處理

—————————

你會處理出錯資訊嗎?哦,它並不是簡單的輸出。看下面的示例:

if ( p == null )

告別學生時代的程式設計吧。這種程式設計很不利於維護和管理,出錯資訊或是提示資訊,應該統一處理,而不是像上面這樣,寫成乙個「硬編碼」。第10條對這方面的處理做了一部分說明。如果要管理錯誤資訊,那就要有以下的處理:

/* 宣告出錯** */

#define     err_no_error    0  /* no error                 */

#define     err_open_file   1  /* open file error          */

#define     err_send_mesg   2  /* sending a message error  */

#define     err_bad_args    3  /* bad arguments            */

#define     err_mem_none    4  /* memeroy is not enough    */

#define     err_serv_down   5  /* service down try later   */

#define     err_unknow_info 6  /* unknow information       */

#define     err_socket_err  7  /* socket operation failed  */

#define     err_permission  8  /* permission denied        */

#define     err_bad_format  9  /* bad configuration file   */

#define     err_time_out   10  /* communication time out   */

/* 宣告出錯資訊 */

char* errmsg = ;

/* 宣告錯誤**全域性變數 */

long errno = 0;

/* 列印出錯資訊函式 */

void perror( char* info)

printf("error: %s/n", errmsg[errno] );}

這個基本上是ansi的錯誤處理實現細節了,於是當你程式中有錯誤時你就可以這樣處理:

bool checkpermission( char* username )

...}

main()

...}

乙個即有共性,也有個性的錯誤資訊處理,這樣做有利同種錯誤出一樣的資訊,統一使用者介面,而不會因為檔案開啟失敗,a程式設計師出乙個資訊,b程式設計師又出乙個資訊。而且這樣做,非常容易維護。**也易讀。

當然,物極必反,也沒有必要把所有的輸出都放到errmsg中,抽取比較重要的出錯資訊或是提示資訊是其關鍵,但即使這樣,這也包括了大多數的資訊。

12、常用函式和迴圈語句中的被計算量

—————————————————

看一下下面這個例子:

for( i=0; i<1000; i++ )

getlocalhostname的意思是取得當前計算機名,在迴圈體中,它會被呼叫1000次啊。這是多麼的沒有效率的事啊。應該把這個函式拿到迴圈體外,這樣只呼叫一次,效率得到了很大的提高。雖然,我們的編譯器會進行優化,會把迴圈體內的不變的東西拿到迴圈外面,但是,你相信所有編譯器會知道哪些是不變的嗎?我覺得編譯器不可靠。最好還是自己動手吧。

同樣,對於常用函式中的不變數,如:

getlocalhostname(char* name)

如果這是乙個經常呼叫的函式,每次呼叫時都要對funcname進行分配記憶體,這個開銷很大啊。把這個變數宣告成static吧,當函式再次被呼叫時,就會省去了分配記憶體的開銷,執行效率也很好。

13、函式名和變數名的命名

————————————

我看到許多程式對變數名和函式名的取名很草率,特別是變數名,什麼a,b,c,aa,bb,cc,還有什麼flag1,flag2, cnt1, cnt2,這同樣是一種沒有「修養」的行為。即便加上好的注釋。好的變數名或是函式名,我認為應該有以下的規則:

1) 直觀並且可以拼讀,可望文知意,不必「解碼」。 

2) 名字的長度應該即要最短的長度,也要能最大限度的表達其含義。

3) 不要全部大寫,也不要全部小寫,應該大小寫都有,如:getlocalhostname 或是 useraccount。

4) 可以簡寫,但簡寫得要讓人明白,如:errorcode -> errcode,  serverlistener -> servlisner,useraccount -> usracct 等。

5) 為了避免全域性函式和變數名字衝突,可以加上一些字首,一般以模組簡稱做為字首。

6) 全域性變數統一加乙個字首或是字尾,讓人一看到這個變數就知道是全域性的。

7) 用匈牙利命名法命名函式引數,區域性變數。但還是要堅持「望文生意」的原則。

8) 與標準庫(如:stl)或開發庫(如:mfc)的命名風格保持一致。

14、函式的傳值和傳指標

————————————

向函式傳引數時,一般而言,傳入非const的指標時,就表示,在函式中要修改這個指標把指記憶體中的資料。如果是傳值,那麼無論在函式內部怎麼修改這個值,也影響不到傳過來的值,因為傳值是只記憶體拷貝。

什麼?你說這個特性你明白了,好吧,讓我們看看下面的這個例程:

void

getversion(char* pstr)

main()

我保證,類似這樣的問題是乙個新手最容易犯的錯誤。程式中妄圖通過函式getversion給指標ver分配空間,但這種方法根本沒有什麼作用,原因就是——這是傳值,不是傳指標。你或許會和我爭論,我分明傳的時指標啊?再仔細看看,其實,你傳的是指標其實是在傳值。

15、修改別人程式的修養

———————————

當你維護別人的程式時,請不要非常主觀臆斷的把已有的程式刪除或是修改。我經常看到有的程式設計師直接在別人的程式上修改表示式或是語句。修改別人的程式時,請不要刪除別人的程式,如果你覺得別人的程式有所不妥,請注釋掉,然後新增自己的處理程式,必竟,你不可能100%的知道別人的意圖,所以為了可以恢復,請不依賴於cvs或是sourcesafe這種版本控制軟體,還是要在原始碼上給別人看到你修改程式的意圖和步驟。這是程式維護時,乙個有修養的程式設計師所應該做的。

如下所示,這就是一種比較好的修改方法: /*

* ----- commented by haoel 2003/04/12 ------

**   char* p = ( char* ) malloc( 10 );

*   memset( p, 0, 10 );

*//* ------ added by haoel   2003/04/12 ----- */

char* p = ( char* )calloc( 10, sizeof char );

/* ---------------------------------------- */

...

當然,這種方法是在軟體維護時使用的,這樣的方法,可以讓再維護的人很容易知道以前的**更改的動作和意圖,而且這也是對原作者的一種尊敬。

以「注釋 — 新增」方式修改別人的程式,要好於直接刪除別人的程式。

原文:

程式設計修養(四)

11 出錯資訊的處理 你會處理出錯資訊嗎?哦,它並不是簡單的輸出。看下面的示例 if p null 告別學生時代的程式設計吧。這種程式設計很不利於維護和管理,出錯資訊或是提示資訊,應該統一處理,而不是像上面這樣,寫成乙個 硬編碼 第10條對這方面的處理做了一部分說明。如果要管理錯誤資訊,那就要有以下...

程式設計修養 四

11 出錯資訊的處理 你會處理出錯資訊嗎?哦,它並不是簡單的輸出。看下面的示例 if p null 告別學生時代的程式設計吧。這種程式設計很不利於維護和管理,出錯資訊或是提示資訊,應該統一處理,而不是像上面這樣,寫成乙個 硬編碼 第10條對這方面的處理做了一部分說明。如果要管理錯誤資訊,那就要有以下...

程式設計修養 推薦

什麼是好的程式設計師?是不是懂得很多技術細節?還是懂底層程式設計?還是程式設計速度比較快?我覺得都不是。對於一些技術細節來說和底層的技術,只要看幫助,查資料就能找到,對於速度快,只要編得多也就熟能生巧了。我認為好的程式設計師應該有以下幾方面的素質 1 有專研精神,勤學善問 舉一反三。2 積極向上的態...