《程式碼之美》的故事
O'REILLY 哪本書封面動物是海鷗?
概況
《程式碼之美》是一本論文集,她彙集33篇技術文章,講述了38位作者認為最漂亮的程式碼。
試列舉部分作者:(對你來說,有幾位是耳熟能詳的?)
- Brian Kernighan:《C程式設計語言》、《程式設計實踐》作者,前一本書也稱K&R
- Charles Petzold:《Windows程式設計》、《編碼的奧祕》作者,Windows專家
- John Bentley:《程式設計珠璣》作者,貝爾實驗室前研究員,普林斯頓大學訪問教授
- Yukihiro Matsumoto(松本行弘):Ruby之父,是一位日本籍的開源倡導者
- Simon Peyton Jones:Haskell主要設計者,GHC編譯器首席設計師
- Douglas Crockford:JSON資料格式發明者,JavaScript領域大牛
《程式碼之美》中文版有七篇推薦序(孟巖、韓磊、熊節、霍泰穩、周愛民、潘加宇、徐繼哲),兩篇譯者序(劉未鵬、聶雪軍),加上目錄共佔據前xxxiv
頁篇幅。(似乎很有一部分讀者詬病推薦序太多)
我於2008年10月24日在網上書店購得《程式碼之美》,有趣的是,版權頁印著“2009年1月第1版第1次印刷”(出版社此舉有何深意,不解ing)。購書當日在CSDN論壇推薦,見文末的參考資料1。
有一幅當時某電商搞笑風格的宣傳海報(似乎改編自《程式碼大全》的海報),可點選參考資料2檢視。
正規表示式匹配器
Brian Kernigham、Rob Pike 合著的《程式設計實踐》第9章 記法
,收錄了許多程式碼示例,很好地說明了優良的記法將產生更好的程式以及更好的設計。(順便說一句,《程式設計實踐》是一本極好的書,強烈推薦)
《程式碼之美》第1章 正規表示式匹配器
講述了當時的情景:Brain 提議用一個最小的正規表示式包作為《程式設計實踐》9.2節
的程式碼示例,它可以很好地詮釋正規表示式的基本思想,並且能夠識別出一組有用且重要的模式。Rob 聽了提議後馬上回到他的辦公室。一兩個小時後他回來了,實現一個正規表示式匹配器:
字元 含義
c 匹配任意的字元 c
. 匹配任意的單個字元
^ 匹配輸入字串的開頭
$ 匹配輸入字串的結尾
* 匹配前一個字元的零個或多個出現
只用了不到30行C程式碼:
/* match: 在 text 中查詢 regexp */
int match(char *regexp, char *text)
{
if (regexp[0] == '^') return matchhere(regexp+1, text);
do { /* 即使字串為空時也必須檢查 */
if (matchhere(regexp, text)) return 1;
} while (*text++ != '\0');
return 0;
}
/* matchhere: 在 text 的開頭查詢 regexp */
int matchhere(char *regexp, char *text)
{
if (regexp[0] == '\0') return 1;
if (regexp[1] == '*' ) return matchstar(regexp[0], regexp+2, text);
if (regexp[0] == '$' && regexp[1] == '\0') return *text == '\0';
if (*text != '\0' && (regexp[0] == '.' || regexp[0] == *text))
return matchhere(regexp+1, text+1);
return 0;
}
/* matchstar: 在 text 的開頭查詢 c*regexp */
int matchstar(int c, char *regexp, char *text)
{
do { /* 萬用字元 * 匹配零個或多個例項 */
if (matchhere(regexp, text)) return 1;
} while (*text != '\0' && (*text++ == c || c == '.'));
return 0;
}
如此少的程式碼實現如此多的功能,同時還提供豐富的內涵和深層次的思想。Brian 認為這是漂亮程式碼的一個極佳示例:緊湊,優雅,高效,實用。也是絕好的遞迴示例。還展示了C指標的強大功能。(熟悉C語言的讀者可自行補上main()
函式,寫出測試程式碼)
為“The Book”編寫程式
《程式碼之美》最後一章說到:數學家 Paul Erdős 經常會談到“The book”,這是一本傳說中的書(在地球上任何一家圖書館裡都找不到),在這本書中記錄了所有數學定理的最優證明。(見參考資料6,推薦數學愛好者閱讀)
Brian Hayes 源於某位朋友的靈感,獲得一個可以寫入演算法藝術領域“The Book”的程式。
這個程式所要解決的是一個非常基本的問題:假定平面內有三個點,那麼這三點是否共線?
Hayes 使用 Lisp 語言編寫程式碼。最初的程式通過比較直線的斜率和截距來判斷共線:
(defun naive-collinear (px py qx qy rx ry)
(let ((m (slope px py qx qy))
(b (y-intercept px py qx qy)))
(= ry (+ (* m rx) b))))
(defun slope (px py qx qy)
(if (= px qx)
nil
(/ (- qy py) (- qx px))))
(defun y-intercept (px py qx qy)
(let ((m (slope px py qx qy)))
(if (not m)
nil
(- py (* m px)))))
(defun less-naive-collinearp (px py qx qy rx ry)
(let ((m (slope px py qx qy))
(b (y-intercept px py qx qy)))
(if (numberp m)
(= ry (+ (* m rx) b))
(= px rx))))
上述程式不夠優雅,對平行於縱座標軸的直線需要特別判斷。
後來,Hayes 閱讀了 Jonathan Richard Shewchuk 的論文,通過計算三角形面積巧妙地解決了三點共線問題。最終版的程式如下:(雖然只有廖廖三行,其豐富的內涵足以寫入“The Book”)
(defun area-collinear (px py qx qy rx ry)
(= (* (- px rx) (- qy ry))
(* (- qx rx) (- py ry))))
題外話:C 和 Lisp
《程式碼之美》第一章和最後一章分別用 C 和 Lisp 語言闡述作者認為最漂亮的程式。《實用 Common Lisp 程式設計》譯者田春在譯者序
末尾說:
C 和 Lisp 是程式語言的兩個極端,大多數人已經熟悉了 C 的那一端,但如果他們還熟悉另一端的話,那麼迅速理解幾乎所有其他的程式語言將不再是問題。
我的O'REILLY書架
我的其他藏書見參考資料7。
參考資料
相關文章
- 程式碼之美---遞迴之美遞迴
- 程式碼之美_感悟
- 《程式碼之美》 ——序
- 享受程式碼之美
- 程式碼之美:重新擦亮思考的火花
- 程式碼之美:又見“鉅著”
- 編碼也快樂:兩水壺的故事之JS程式JS
- 程式碼故事:漢德的救贖
- 程式碼規範&《數學之美》讀後感
- 從美術生到程式設計師轉型之路【我的故事】程式設計師
- 程式碼審查的藝術:Dropbox 的故事
- 程式設計之美之電話號碼對應英語單詞程式設計
- 程式之美 存乎於心
- 程式設計之美之買票找零程式設計
- 指令碼的故事(2)指令碼
- 指令碼的故事(4)指令碼
- 美觀的搜尋框程式碼例項
- 開發者故事|程式碼虐我千萬遍,我待程式碼如“初戀”
- 演算法之美一書完整程式碼釋出連結整理演算法
- 程式設計師必看:程式的美,不止動畫的美程式設計師動畫
- 程式設計之美複習筆記程式設計筆記
- 程式設計之美之高效安排見面會程式設計
- 程式設計之美之最短摘要生成程式設計
- 艱難前行的故事 (《夢斷程式碼》讀後感)薦
- Golang之美Golang
- go原始碼解析-Println的故事Go原始碼
- Go併發程式設計之美-CAS操作Go程式設計
- Go併發程式設計之美-互斥鎖Go程式設計
- 程式設計之美leetcode之編輯距離程式設計LeetCode
- 碼農故事:一位中級程式設計師的自白程式設計師
- 野生程式設計師的故事程式設計師
- 美國碼農故事:寫程式碼獲得陸軍嘉獎獎章
- 指令碼之美│VBS 入門互動實戰指令碼
- 遞迴之美 - Loki庫TypeList原始碼剖析 (轉)遞迴Loki原始碼
- 美觀開關按鈕程式碼例項
- 對齊之美
- 微信小程式實戰(一)之仿美麗說微信小程式
- 程式設計之美初賽第一場--焦距程式設計