閱讀程式碼的動作,可以是很原始的,利用最簡單的文字編輯器,逐一開啟原始碼,然後憑藉著一己的組織能力,在不同的程式碼間跳躍,拼湊出腦中想要構建的圖像。

不過,系統的複雜度往往超過人腦的負荷。閱讀程式碼的時候,你會需要更多工具提供協助。使用好的整合式開發環境(IDE)或文字編輯器,就能提供最基本的幫助。

善用文字編輯器或IDE,加速解讀程式碼
許多文字編輯器提供了常見程式語言的語法及關鍵字標示功能。這對於閱讀來說,絕對能夠起很大的作用。有些文字編輯器(例如我常用的EditPlus及偶而使用的Notepad++),甚至能夠自動列出某個原始檔中所有定義的函式清單,更允許你直接從清單中選擇函式,直接跳躍到該函式的定義位置。這對於閱讀程式碼的人來說,就提供了極佳的便利性。

因為在閱讀程式碼時,最常做的事,就是隨著程式中的某個控制流,將閱讀的重心,從某個函式移至它所呼叫的另一個函式。所以對程式人來說,閱讀程式碼時最常做的事之一就是:找出某個函式位在那一個原始檔裡,接著找到該函式所在的位置。

好的IDE能夠提供的協助就更多了。有些能夠自動呈現一些額外的資訊,最有用的莫過於函式的原型宣告了。例如,有些IDE支援當游標停留在某函式名稱上一段時間後,它會以Tooltip的方式顯示該函式的原型宣告。

對閱讀程式碼的人來說,在看到程式碼中呼叫到某個函式時,可以直接利用這樣的支援,立即取得和這個函式有關的原型資訊,馬上就能知道呼叫該函式所傳入的各個引數的意義,而不必等到將該函式的定義位置找出後,才能明白這件事。

grep是一個基本而極為有用的工具
除了選用好的文字編輯器或IDE之外,還有一個基本、但卻極為有用的工具,它就是grep。熟悉Unix作業系統的程式人,對grep這個公用程式多半都不陌生。Grep最大的用途,在於它允許我們搜尋某個目錄(包括遞迴進入所有子目錄)中所有指定檔案,是否有符合指定條件(常數字串或正規表示式)檔案。

倘若有的話,則能幫你指出所在的位置。這在閱讀程式碼時的作用極大。當我們隨著閱讀的腳步,遇上了任何一個不認識、但自認為重要的類別、函式、資料結構定義或變數,我們就得找出它究竟位在這茫茫程式碼海中的何處,才能將這個圖塊從未知變為已知。

grep之所以好用,就是在於當我們發現某個未知的事物時,可以輕易地利用它找出這個未知的事物究竟位在何方。此外,雖說grep是Unix的標準公用程式之一,但是像Windows這樣子的平臺,也有各種類型的grep程式。對於在Windows環境工作的程式人來說,可以自行選用覺得稱手的工具。

gtags可建立索引,讓搜尋更有效率
grep雖然好用,但是仍然有一些不足之處。第一個缺點在於它並不會為所搜尋的原始碼檔案索引。每當你搜尋時,它都會逐一地找出所有的檔案,並且讀取其中的所有內容,過濾出滿足指定條件的檔案。當專案的原始碼數量太大時,就會產生搜尋效率不高的問題。

第二個缺點是它只是一個單純的文字檔搜尋工具,本身並不會剖析原始碼所對應的語言語法。當我們只想針對「函式」名稱進行搜尋時,它有可能將註解中含有該名稱的原始碼,也一併找了出來。

針對grep的缺點,打算閱讀他人程式碼的程式人,可以考慮使用像是gtags這樣子的工具。gtags是GNU GLOBAL source code tag system,它不只搜尋文字層次,而且因為具備了各種語言的語法剖析器,所以在搜尋時,可以只針對和語言有關的元素,例如類別名稱、函式名稱等。

而且,它能針對原始碼的內容進行索引,這意謂一旦建好索引之後,每次搜尋的動作,都毋需重新讀取所有原始碼的內容並逐一搜尋。只需要以現成的索引結構為基礎,即可有效率的尋找關鍵段落。

gtags提供了基於命令列的程式,讓你指定原始碼所在的目錄執行建立索引的動作。它同時也提供程式讓你得如同操作grep一般,針對索引結構進行搜尋及檢索。它提供了許多有用的檢索方式,例如找出專案中定義某個資料結構的檔案及定義所在的行號,或者是找出專案中所有引用某資料結構的檔案,以及引用處的行號。

這麼一來,你就可以輕易地針對閱讀程式碼時的需求予以檢索。相較於grep所能提供的支援,gtags這樣的工具,簡直是強大許多。

再搭配htags製作HTML文件,更是如虎添翼
還有一個絕對需要一提的工具。這個叫做htags的工具,能夠幫你將已製作完成的索引結構,製作成為一組相互參考的HTML文件。基本上,利用這樣的HTML文件閱讀程式碼,比起單純地直接閱讀原始碼,來得更有結構。原因是閱讀程式碼時,這樣的HTML文件,已經為你建立起在各個原始碼檔案片段間跳躍的鏈結。例如,圖一是針對一個有名的開放原始碼專案ffmpeg,由gtags所產生出來的HTML文件首頁的一部分。


htags工具首先為你找出所有定義main()函式的檔案,並且列出所在的函式。找出main()函式,時常是閱讀程式碼的第一步,因為main()函式是程式的主要入口點,所有的動作皆由此啟動,它是一切事物的源頭。

憑藉htags製作的HTML文件,你可以輕易地點擊超連結,直接進到main()函式所在的程式碼片段,如圖二。



當我們檢視上述原始碼時,發現av_register_all()是個陌生、無法了解的事物,而想要搞懂它究竟是什麼,可以再繼續點擊這個函式,如圖三。這真是太方便了!閱讀至此,你會猛然發現,gtags彷彿就是為了閱讀程式碼而專門量身打造的利器。



作者簡介:
王建興
清華大學資訊工程系的博士研究生,研究興趣包括電腦網路、點對點網路、分散式網路管理、以及行動式代理人,專長則是Internet應用系統的開發。曾參與過的開發專案性質十分廣泛而且不同,從ERP、PC Game到P2P網路電話都在他的涉獵範圍之內。

相關連結
閱讀他人的程式碼(6)閱讀的樂趣:透過程式碼認識作者
閱讀他人的程式碼(5)找到程式入口,再由上而下抽絲剝繭
閱讀他人的程式碼(4)望文生義,進而推敲組件的作用
閱讀他人的程式碼(2)摸清架構,便可輕鬆掌握全貌
閱讀他人的程式碼(1)讀懂程式碼,使心法皆為我所用

熱門新聞

Advertisement