1. 程式人生 > >拿到一個程式碼,如何快速分析專案結構與各函式關係?

拿到一個程式碼,如何快速分析專案結構與各函式關係?

第一章: 導論

++++++++++++


1.要養成一個習慣, 經常花時間閱讀別人編寫的高品質程式碼.

2.要有選擇地閱讀程式碼, 同時, 還要有自己的目標. 您是想學習新的模式|編碼風格|還是滿足某些需求的方法.

3.要注意並重視程式碼中特殊的非功能性需求, 這些需求也許會導致特殊的實現風格.

4.在現有的程式碼上工作時, 請與作者和維護人員進行必要的協調, 以避免重複勞動或產生厭惡情緒.

5.請將從開放原始碼軟體中得到的益處看作是一項貸款, 儘可能地尋找各種方式來回報開放原始碼社團.

6.多數情況下, 如果您想要了解"別人會如何完成這個功能呢?", 除了閱讀程式碼以外, 沒有更好的方法.

7.在尋找bug時, 請從問題的表現形式到問題的根源來分析程式碼. 不要沿著不相關的路徑(誤入歧途).


8.我們要充分利用偵錯程式|編譯器給出的警告或輸出的符號程式碼|系統呼叫跟蹤器|資料庫結構化查詢語言的日誌機制|包轉儲工具和Windows的訊息偵查程式, 定出的bug的位置.

9.對於那些大型且組織良好的系統, 您只需要最低限度地瞭解它的全部功能, 就能夠對它做出修改.

10.當向系統中增加新功能時, 首先的任務就是找到實現類似特性的程式碼, 將它作為待實現功能的模板.

11.從特性的功能描述到程式碼的實現, 可以按照字串訊息, 或使用關鍵詞來搜尋程式碼.

12.在移植程式碼或修改介面時, 您可以通過編譯器直接定位出問題涉及的範圍, 從而減少程式碼閱讀的工作量.

13.進行重構時, 您從一個能夠正常工作的系統開始做起, 希望確保結束時系統能夠正常工作. 一套恰當的測試用例(test case)可以幫助您滿足此項約束.


14.閱讀程式碼尋找重構機會時, 先從系統的構架開始, 然後逐步細化, 能夠獲得最大的效益.

15.程式碼的可重用性是一個很誘人, 但難以理解與分離, 可以試著尋找粒度更大一些的包, 甚至其他程式碼.

16.在複查軟體系統時, 要注意, 系統是由很多部分組成的, 不僅僅只是執行語句. 還要注意分析以下內容: 檔案和目錄結構|生成和配置過程|

使用者介面和系統的文件.

18.可以將軟體複查作為一個學習|講授|援之以手和接受幫助的機會.

++++++++++++++++++++

第二章: 基本程式設計元素

++++++++++++++++++++



19.第一次分析一個程式時, main是一個好的起始點.

20.層疊if-else if-...-else序列可以看作是由互斥選擇項組成的選擇結構.


21.有時, 要想了解程式在某一方面的功能, 執行它可能比閱讀原始碼更為恰當.

22.在分析重要的程式時, 最好首先識別出重要的組成部分.

23.瞭解區域性的命名約定, 利用它們來猜測變數和函式的功能用途.

24.當基於猜測修改程式碼時, 您應該設計能夠驗證最初假設的過程. 這個過程可能包括用編譯器進行檢查|引入斷言|或者執行適當的測試用例.

25.理解了程式碼的某一部分, 可能幫助你理解餘下的程式碼.

26.解決困難的程式碼要從容易的部分入手.

27.要養成遇到庫元素就去閱讀相關文件的習慣; 這將會增強您閱讀和編寫程式碼的能力.

28.程式碼閱讀有許多可選擇的策略: 自底向上和自頂向下的分析|應用試探法和檢查註釋和外部文件, 應該依據問題的需要嘗試所有這些方法.

29.for (i=0; i<n; i++)形式的迴圈執行n次; 其他任何形式都要小心.

30.涉及兩項不等測試(其中一項包括相等條件)的比較表示式可以看作是區間成員測試.

31.我們經常可以將表示式應用在樣本資料上, 藉以瞭解它的含義.

32.使用De Morgan法則簡化複雜的邏輯表示式.

33.在閱讀邏輯乘表示式時, 問題可以認為正在分析的表示式以左的表示式均為true; 在閱讀邏輯和表示式時, 類似地, 可以認為正在分析的表示式以左的表示式均為false.

34.重新組織您控制的程式碼, 使之更為易讀.

35.將使用條件執行符? :的表示式理解為if程式碼.

36.不需要為了效率, 犧牲程式碼的易讀性.

37.高效的演算法和特殊的優化確實有可能使得程式碼更為複雜, 從而更難理解, 但這並不意味著使程式碼更為緊湊和不易讀會提高它的效率.

38.創造性的程式碼佈局可以用來提高程式碼的易讀性.

39.我們可以使用空格|臨時變數和括號提高表示式的易讀性.

40.在閱讀您所控制的程式碼時, 要養成添加註釋的習慣.

41.我們可以用好的縮排以及對變數名稱的明智選擇, 提高編寫欠佳的程式的易讀性.

42.用diff程式分析程式的修訂歷史時, 如果這段歷史跨越了整體重新縮排, 常常可以通過指定-w選項, 讓diff忽略空白差異, 避免由於更改了縮排層次而引入的噪音.

43.do迴圈的迴圈體至少執行一次.

44.執行算術運算時, 當b=2n-1時, 可以將a&b理解為a%(b+1).

45.將a<<n理解為a*k, k=2n.

46.將a>>n理解為a/k, k=2n.

47.每次只分析一個控制結構, 將它的內容看作是一個黑盒.

48.將每個控制結構的控制表示式看作是它所包含程式碼的斷言.

49.return, goto, break和continue語句, 還有異常, 都會影響結構化的執行流程. 由於這些語句一般都會終止或重新開始正在進行的迴圈, 

因此要單獨推理它們的行為.

50.用複雜迴圈的變式和不變式, 對迴圈進行推理.

51.使用保持含義不變的變換重新安排程式碼, 簡化程式碼的推理工作.