# 導言:C的笛卡爾之夢
> 原文:[Introduction: The Cartesian Dream Of C](http://c.learncodethehardway.org/book/introduction.html)
> 譯者:[飛龍](https://github.com/wizardforcel)
‍
> 直到現在,凡是我當作最真實、最可靠而接受的東西,都是從感官或通過感官得來的。不過,我有時覺得這些感官是騙人的,并且為了小心謹慎起見,對于一經騙過我們的東西就決不完全加以信任。
> 勒內·笛卡爾,《第一哲學沉思錄》
如果有一段引述用來描述C語言編程的話,那就是它了。對于大多數程序員,C是極其可怕而且邪惡的。他就像是惡魔、撒旦,或者一個使用指針的花言巧語和對機器的直接訪問來破壞你生產力的騙子洛基。于是,一旦這位計算界的路西法將你纏住,他就會使用邪惡的“段錯誤”來毀掉你的世界,并且揭露出與你交易中的騙局而嘲笑你。
然而,C并不應由于這些現實而受到責備。你的電腦和控制它的操作系統才是真正的騙子,而不是朋友。它們通過密謀來向你隱藏它們的真實執行邏輯,使你永遠都不真正知道背后發生了什么。C編程語言的失敗之處只是向你提供接觸背后真正工作原理的途徑,并且告訴了你一些難以接受的事實。C會向你展示痛苦的真像(紅色藥丸),它將幕布拉開來向你展示一些神奇的原理。C即是真理。
既然C如此危險,為什么還要使用它?因為C給了你力量來穿越抽象的假象,并且將你從愚昧中解放出來。
## 你會學到什么
這本書的目的是讓你足夠熟悉C語言,并能夠使用它編寫自己的軟件,或者修改其他人的代碼。這本書的最后,我們會從一本叫做“K&R C”的名著中選取實際的代碼,并且用你學過的知識來做代碼審查。你需要學習下面這些東西來達到這一階段:
+ C的基本語法和編寫習慣。
+ 編譯,`make`文件和鏈接。
+ 尋找和預防bug。
+ 防御性編程實踐。
+ 使C的代碼崩潰。
+ 編寫基本的Unix系統軟件。
截至最后一章,你將會有足夠的工具來解決基本的系統軟件、庫和其它小項目。
## 如何閱讀本書
這本書為那些已經掌握至少一門編程語言的人而設計。如果你還沒有接觸過編程,我推薦你先學習[笨辦法學Python](http://learnpythonthehardway.org/),這本書適用于真正的新手并且適合作為第一本編程書。一旦你學會了Python,你可以返回來開始學習這本書。
對于那些已經學會編程的人,這本書的開頭可能有些奇怪。它不像其它書一樣,那些書中你會閱讀一段段的文字然后編寫一些代碼。相反,這本書中我會讓你立即開始編程,之后我會解釋你做了什么。這樣更有效果,因為你已經經歷過的事情解釋起來更加容易。
由于采用了這樣的結構,下面是本書中你必須遵守的規則:
+ 手動輸入所有代碼。不要復制粘貼!
+ 正確地輸入所有代碼,也包括注釋。
+ 運行代碼并保證產生相同的輸出。
+ 如果出現了bug則修正它。
+ 做附加題時,如果你做不出某道題,馬上跳過。
+ 在尋求幫助之前首先試著自己弄懂。
如果你遵守了這些規則,完成了本書的每一件事,并且還不會編程C代碼的話,你至少嘗試過了。它并不適用于每個人,但是嘗試的過程會讓你成為一個更好的程序員。
## 核心能力
我假設你之前使用為“弱者”設計的語言。這些“易用的”語言之一是Python或者Ruby,它們帶給了你草率的思維和半吊子的黑魔法。或者,你可能使用類似Lisp的語言,它假設計算機是純函數式的奇幻大陸,帶有一些為嬰兒準備的充氣墻。再或者你可能學過Prolog,于是你認為整個世界都是一個數據庫,你可以從中尋找線索。甚至更糟糕的是,我假設你一直都在用IDE,所以你的大腦布滿了內存漏洞,并且你每打三個字符都要按CTRL+空格來打出函數的整個名字。
無論你的背景如何,你都可能不擅長下面四個技能:
閱讀和編寫
如果你使用IDE這會尤其正確。但是總體上我發現程序員做了很多“略讀”,并且在理解上存在問題。它們會略讀需要詳細理解的代碼,并且覺得他們已經理解了但事實上沒有。其它語言提供了可以讓他們避免實際編寫任何代碼的工具,所以面對一種類似C的語言時,他們就玩完了。你需要知道每個人都有這個問題,并且你可以通過強迫自己慢下來并且仔細對待閱讀和編寫代碼來改正它。一開始你可能感到痛苦和無聊,但是這樣的次數多了它也就變得容易了。
專注細節
每個人都不擅長這方面,它也是劣質軟件的罪魁禍首。其它語言讓你不會集中注意力,但是C要求你集中全部注意力,因為它直接在機器上運行,并且機器比較挑剔。C中沒有“相似的類型”或者“足夠接近”,所以你需要注意,再三檢查你的代碼,并假設你寫的任何代碼都是錯的,直到你能證明它是對的。
定位差異
其它語言程序員的一個關鍵問題就是他們的大腦被訓練來指出那個語言的差異,而不是C。當你對比你的代碼和我練習中的代碼時,你的眼睛會跳過你認為不重要或者不熟悉的字符。我會給你一些策略來強制你觀察你的錯誤,但是要記住如果你的代碼并不完全像書中的代碼,它就是錯的。
規劃和調試
我喜歡其它較簡單的語言,因為我可以想怎么寫就怎么寫。我將已有的想法輸入進解釋器,然后可以立即看到結果。你可以把你的想法試驗出來,但是要注意,如果你仍然打算“試驗代碼使其能夠工作”,它就行不通了。C對于你來說稍困難,因為你需要規劃好首先創建什么。的確,你也可以進行試驗,但是比起其他語言,你必須在C中更早地嚴肅對待代碼。我會教給你在編程之前規劃程序核心部分的方法,這對于使你成為更好的程序員十分有幫助。即使一個很小的規劃,都會使接下來的事情變得順利。
學習C語言會使你變成更好的程序員,因為會強制你更早、更頻繁地解決這些問題。你不會再草率地編寫半吊子的代碼,代碼也會能夠正常工作。C的優勢是,它是一個簡單的語言,你可以自己來弄清楚,這使得它成為用于學習機器,以及提升程序員核心技能的最佳語言。
C比其它語言都要難,而這是由于C并不對你隱藏細節,它們在其它語言中都試圖并且未能被掩蓋。
## 協議
原書在完稿之后可以自由分發,并且能在[亞馬遜](http://www.amazon.com/Learn-Hard-Way-Practical-Computational/dp/0321884922/)上購買。該中譯版本遵循[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)協議,你可以在保留署名和出處的前提下以非商業目的自由轉載。
- 笨辦法學C 中文版
- 前言
- 導言:C的笛卡爾之夢
- 練習0:準備
- 練習1:啟用編譯器
- 練習2:用Make來代替Python
- 練習3:格式化輸出
- 練習4:Valgrind 介紹
- 練習5:一個C程序的結構
- 練習6:變量類型
- 練習7:更多變量和一些算術
- 練習8:大小和數組
- 練習9:數組和字符串
- 練習10:字符串數組和循環
- 練習11:While循環和布爾表達式
- 練習12:If,Else If,Else
- 練習13:Switch語句
- 練習14:編寫并使用函數
- 練習15:指針,可怕的指針
- 練習16:結構體和指向它們的指針
- 練習17:堆和棧的內存分配
- 練習18:函數指針
- 練習19:一個簡單的對象系統
- 練習20:Zed的強大的調試宏
- 練習21:高級數據類型和控制結構
- 練習22:棧、作用域和全局
- 練習23:認識達夫設備
- 練習24:輸入輸出和文件
- 練習25:變參函數
- 練習26:編寫第一個真正的程序
- 練習27:創造性和防御性編程
- 練習28:Makefile 進階
- 練習29:庫和鏈接
- 練習30:自動化測試
- 練習31:代碼調試
- 練習32:雙向鏈表
- 練習33:鏈表算法
- 練習34:動態數組
- 練習35:排序和搜索
- 練習36:更安全的字符串
- 練習37:哈希表
- 練習38:哈希算法
- 練習39:字符串算法
- 練習40:二叉搜索樹
- 練習41:將 Cachegrind 和 Callgrind 用于性能調優
- 練習42:棧和隊列
- 練習43:一個簡單的統計引擎
- 練習44:環形緩沖區
- 練習45:一個簡單的TCP/IP客戶端
- 練習46:三叉搜索樹
- 練習47:一個快速的URL路由
- 后記:“解構 K&R C” 已死