編寫優質無錯程式碼(3) (轉)

gugu99發表於2008-01-25
編寫優質無錯程式碼(3) (轉)[@more@]不是,則返回-1。
缺點在於:把錯誤標誌值和計算結果混在一起使用,容易造成使用者的誤會。

b.該使用了斷言,如果ch在A..Z之間則返回相應的小寫字元,如果不是,
斷言會起作用,發生錯誤並退出。而最後一個return ch;則是在
release的時候,如果不是A..Z之間,則返回原來的字元。但是,從書寫效
率上來說,這個函式稍微羅嗦了一點。因為它重複使用了斷言和if判斷。

c.該函式也使用了斷言,返回相應大寫字母的小寫字母。

使用斷言的好處:
a.暴露了者的錯誤
b.便於
c.對程式碼沒有代價
d.最少的處理代價

斷言使用舉例:
void memcpy(void * pvTo,void *pvFrom,size_t size){
void *pbTo= (byte *)pvTo;
void *pbFrom= (byte * pvFrom);
assert(pvTo !=NULL && pvFrom !=NULL);
assert(pbTo >= pbFrom +sizepbFrom >= pbTo+size);

}

使用斷言的規則:
a.要使用斷言對函式引數進行確認
b.要從程式中刪去無定義的特性或者在程式中使 用斷言來檢查出無定義特性
的使用
c.不要浪費別人的時間-詳細說明不清楚的斷言
d.消除所做的隱式假定,或者利用檢查其正確性
e.在進行防錯性時,不要隱瞞錯誤
防錯性程式設計雖然被譽為有較好的編碼風格,但它卻隱瞞了錯誤。
要記住,我們正在談論的錯誤決不應該再發生,而對這些錯所進行的處理
又編寫無錯程式碼變得更加困難
f.要利用不同的演算法對程式的結果進行確認
g.不要等待錯誤發生,要使用初始檢查程式

斷言小結:
a.要同時維護交付和除錯兩個版本。封裝交付的版本,應儘可能地使用調
試版本進行自動查錯。
b.斷言是進行除錯檢查的簡單方法。要使用斷言捕捉不應該發生的非法情
況。不要混淆非法情況與錯誤情況之間的區別,後者是在最終產品中必須
處理的。
c.使用斷言對函式的引數進行確認,並且在程式設計師使用了無定義的特性時
向程式設計師報警。涵數定義得越嚴格,確認其引數就越容易。
d.防錯性程式設計會隱瞞錯誤。在進行防錯編碼時,如果”不可能發生”的
情況確實發生了,要使用斷言進行報警。


寫到這裡,我們初步探討了編寫優質無錯程式碼的必要性,原則,和相關。
留幾個練習題目,大家也參與一下討論吧。
練習題目1:
下面的memset函式實現有什麼問題?

void *memset(void *pv, byte b, size_t size)
{
byte *pb = (byte *)pv;
unsigned long l;
size_t sizeSize;

l = (b << 8) | b; /* 用4個位元組拼成一個long */
l = (l << 16) | l;
pb = (byte *)longfill((long *)pb, l, size/4);
size = size % 4;

while (size-- > 0)
*pb++ = b;
return (pv);
}

練習題目2:

下面的程式碼用memset將三個區域性變數置為0,請問可能會有什麼問題?
void DoSomeThing(...)
{
int i;
int j;
int k;

memset(&k, 0, 3*sizeof(int)); // 將i,j,k置為0
...
}

練習題目3:

定義結構如下:
typedef struct
{
char c1;
char c2;
int n;
} stru;
請問sizeof(stru)等於多少?並說明理由。

練習題目4:

下面是C語言中兩種if語句判斷方式。請問哪種寫法更好?為什麼?
int n;

if (n == 10) // 第一種判斷方式
if (10 == n) // 第二種判斷方式

練習題目5:

下面的程式碼有什麼問題?
void DoSomeThing(...)
{
char* p;
...
p = malloc(1024); // 分配1K的空間
if (NULL == p)
return;
...
p = realloc(p, 2048); // 空間不夠,重新分配到2K
if (NULL == p)
return;
...
}

練習題目6:

下面的程式碼有什麼問題?
char *DoSomeThing(...)
{
char str[16];

...
return str;
}

練習題目7:
下面的程式碼有什麼問題?

char *_strdup( const char *str )
{
static char str[MAX_STR_LEN];

strcpy(str, strSource);
return str;
}

練習題目8:

下面的程式碼有什麼問題?並請給出正確的寫法。
try{
FILE* fp = fopen("c:1.dat");
if (NULL != fp)
{
...
}
fclose(fp);
}
except(EXCEPTION_EXECUTE_HANDLER){
}

我敲字敲累了,告一段落吧。不過,討論會並不止討論了這些內容,還有很
多內容我沒有寫完,比如,函式的介面, 編寫程式碼的風險, 的態度等等
問題。作為補充,我把討論會的幻燈片修改成了文字版本,作為另外一篇文
章放在這裡,以便對這個話題感興趣的網友們參考。
有什麼問題,歡迎來信 ariesram@aid.com.cn 繼續探討。


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

相關文章