程式設計的過程如同一個編製漁網的人, 親手將一條條程式碼, 編製成一張邏輯的大網. 漁夫拿著你的漁網出海捕魚, 被困住的魚群,則不斷地在網中,尋找網子的邏輯漏洞.
如果網子製作的夠牢固, 那麼漁夫就可以利用這個網子補到大量的魚獲. 反之, 則不僅造成經濟上的損失, 而充滿邏輯漏洞的程式也會造成安全上的問題.
不好的習慣程式設計習慣 -> 大量時間的除錯.
嚴謹的程式設計行為 -> 高品質的程式
列出幾項要注意的事項, 提醒我自己 ....
1. 若使用 if, 則一定要搭配 else
if(btest){ ...
}else{ ... }
2. function 或 method 如有必要, 則一定要有成功與否的回傳值.
要點 1, 2, 保證了程式所有的邏輯都會強迫自己考慮, 以減少將來自己修補邏輯漏洞的機會.
下面列出 "完美程式設計指南" 讀書心得
惡魔躲在細節中
1. 使用 Assert 把非計畫中的狀況找出來
=> 你可以在程式中設下非常多除錯檢查巨集跟除錯程式碼,讓臭蟲很快就會被這些警報系統逮個正著
2. 記憶體處理
配置記憶體
=> 將未初始化的記憶體以某個垃圾值填滿,
那樣子如果有參考到未初始化記憶體的情形發生, 你就可以在每次執行到出錯的程式時都能重複同樣的現象
=> 微軟的應用程式用0xCC來填寫剛配置出來的記憶體塊,因為這數字夠大,容易注意到, 而且如果被執行到,會自動呼叫除錯器的中斷點處理。
(這個值本身就是Intel 80x86微處理器用來當作除錯中斷點指令用的。)
------------------------- code -----------------------
#define bGarbage 0xCC
flag fNewMemory(void **ppv, size_t size){
byte **ppb = (byte * )ppv;
ASSERT(ppv != NULL && size != 0);
*ppb = (byte *)malloc(size);
#ifdef DEBUG
{
if (*ppb != NULL)
memset(*ppb, bGarbage, size);
}
#endif
return (*ppb != NULL);
}
------------------ end of code -----------------
釋放記憶體: 把他清乾淨, 不然別處的程式可能會繼續使用這些已釋放記憶體中的東西而不被察覺。
------------------------- code -----------------------
void FreeMemory(void *pv)
{
ASSERT(pv != NULL);
#ifdef DEBUG
{
memset(pv, bGarbage, sizeofBlock(pv));
}
#endif
free(pv);
}
------------------ end of code -----------------
3. 追蹤記憶體配置的紀錄, 以便管理
/* 幫新記憶體塊建立一筆記錄。 */
flag fCreateBlockInfo(byte *pbNew, size_t sizeNew);
/* 釋放一塊記憶體的紀錄資訊。 */
void FreeBlockInfo(byte *pb);
4. 壞人如果都不出城,那在出城的路上設下路障有什麼用
=> 自己隨時察看 code, 把壞人找出來
=> 真正給資料去跑各種狀況, 追蹤程式中每一條執行路線至少一次,以確保程式的正確無誤
=> 如果同個程式碼不管輸入狀態如何都會執行,你就降低了找不出錯誤的機率。
小心設計測試檢查。
沒有東西是可以隨便來的。
5. 讓錯誤狀態難以忽略。不要將錯誤代碼跟別的輸出結果一起放在返回值中。
flag function(char *pch);
6. 在面試時詢問求職者技術問題的政策
怎樣寫出一個會將大寫字元轉換成小寫字元的函式?
char tolower(char ch)
{
return (ch + 'a' - 'A');
}
程式中怎樣檢查錯誤?符號跟小寫字元會被忽略掉嗎?
by Jing
沒有留言:
張貼留言