前言

這本書有什麼特點?面向什麼樣的讀者?

這本書最初是為北京亞嵌教育研究中心的嵌入式Linux系統工程師就業班課程量身定做的教材之一。該課程是為期四個月的全日制職業培訓,要求學員畢業時具備非常Solid的C編程能力,能熟練地使用Linux系統,同時對計算機體繫結構與指令集、操作系統原理和設備驅動程式都有較深入的瞭解。然而學員入學時的水平是非常初級而且參差不齊的:學歷有專科、本科也有研究生,專業有和計算機相關的也有很不相關的(例如會計專業),以前從事的職業有和技術相關的也有完全不相關的(例如HR),年齡從二十出頭到三十五六歲的都有。這麼多背景完全不同、基礎完全不同、思維習慣和理解能力完全不同的人來聽同一堂課,大家都迫切希望學會嵌入式開發技術,投身IT行業,這就是職業教育的特點,也是我編這本書時需要考慮的主要問題。

學習編程絶不是一件簡單的事,尤其是對於零基礎的初學者來說。大學的計算機專業有四年時間從零基礎開始培養一個人,微積分、綫代、隨機、離散、組合、自動機、編譯原理、操作系統、計算機組成原理等等一堆基礎課,再加上C/C++、Java、資料庫、網絡、軟件工程、計算機圖形學等等一堆專業課,最後培養出一個能找到工作的學生。很遺憾這最後一條很多學校沒有做好,來亞嵌培訓的很多學生就是四年這麼學過來的,但據我們考查他們的基礎几乎為零,我不知道為什麼。與之形成鮮明對比的是,只給我們四個月的時間,同樣要求從零基礎開始,最後培養出一個能找到工作的學生,而且還要保證他找到工作,這就是職業教育的特點。

為什麼我說“只給我們四個月的時間”?我們倒是想教四年呢,但學時的長短我們做不了主,是由市場規律決定的。四年的任務要求四個月做好,要怎麼完成這樣一個几乎不可能的任務?有些職業教育給出的答案是“實用主義”,打出了“有用就學,沒有用就不學”的口號,大肆貶低說大學裡教的基礎課都是過時的、無用的,只有他們教的技術才是實用的,這種炒作很不好,我認為大學裡教的每一門課都是非常有用的,基礎知識在任何時候都不會過時,倒是那些時髦的“實用技術”有可能很快就過時了。

四年的任務怎麼才能用四個月做好?我們給出的答案是“優化”。現在大學裡安排的課程體系最大的缺點就是根本不考慮優化。每個過來人都會有這樣的感覺:大一大二學了好多數學課,卻不知道都是幹什麼用的,為什麼要學。連它有什麼用都不知道怎麼能有興趣學好呢?然後到大三大四學專業課時,用到以前的知識了,才發現以前學的數學是多麼有用,然而早就忘得一乾二淨了,考完試都還給老師了,回頭重新學吧,這時候才發現很多東西以前根本沒學明白,現在才真的學明白了,那麼前兩年的時間豈不是都浪費了?大學裡的課程體系還有一個缺點就是不靈活,每門課必須占一個學期,必須由一個老師教,不同課程的老師之間沒有任何溝通和銜接,其實這些課程之間是相互依賴的,把它們強行拆開是不符合人的認知規律的。比如我剛上大學的時候,大一上半學期就被逼着學C語言,其實C語言是一門很難的編程語言,不懂編譯原理、操作系統和計算機體繫結構根本不可能學明白,那半個學期自然就浪費掉了。當時几乎所有學校的計算機相關專業都是這樣,大一上來就學C語言,有的學校更瘋狂,上來就學C++,導致大多數學生都以為自己會C語言,但其實都是半吊子水平,到真正寫代碼的時候經常為一個Bug搞得焦頭爛額,卻沒有機會再系統地學一遍C語言,因為在學校看來,C語言課早在大一就給你“上完了”,就像一頓飯已經吃完了,不管你吃飽沒吃飽,不會再讓你重吃一遍了。顯而易見,如果要認真地對這些課程做優化,的確是有很多水份可以擠的。

本書有以下特點:

  • 不是孤立地講C語言,而是和編譯原理、操作系統、計算機體繫結構結合起來講。或者說,本書的內容只是以C語言為載體,真正講的是計算機的原理和程序的原理。

  • 強調基本概念和基本原理,在編排順序上非常重視概念之間的依賴關係,每次引入一個新的概念,只依賴于前面章節已經講過的概念,而絶不會依賴後面章節要講的概念。有些地方為了敘述得完整,也會引用後面要講的內容,比如說“有關XX我們到XX章再仔細講解”,凡是這種引用都不是必要的依賴,可以當它不存在,只管繼續往下看就行了。

  • 儘量做到每個知識點直到要用的時候才引入。過早引入一個知識點,講完了又不用它,讀者很快就會遺忘,這是不符合認知規律的。

這是一本從零基礎開始學習編程的書,不要求讀者有任何編程經驗,但讀者至少需要具備以下素質:

  • 熟悉Linux系統的基本操作。如果不具備這一點,請先參考其它教材學習Linux系統的基本操作,熟練之後再學習本書,《鳥哥的Linux私房菜》據說是Linux系統管理和應用方面比較好的一本書。但學習本書並不需要會很多系統管理技術,只要會用基本命令,會自己安裝系統和軟件包就足夠了。

  • 具有高中畢業的數學水平。本書會用到高中的數學知識,事實上,如果不具有高中畢業的數學水平,也不必考慮做程序員了。但並不是說只要具有高中畢業的數學水平就足夠做程序員了,只能說看這本書應該沒有問題,數學是程序員最重要的修養,計算機科學其實就是數學的一個分支,如果你的數學功底很差,日後還需惡補一下。

  • 具有高中畢業的英文水平。理由同上。

  • 對計算機的原理和本質深感興趣,不是為就業而學習,不是為拿高薪而學習,而是真的感興趣,想把一切來龍去脈搞得清清楚楚而學習。

  • 勤於思考。本書盡最大努力理清概念之間的依賴關係,力求一站式學習,讀者不需要為了找一個概念的定義去翻其它書,也不需要為了搞清楚一個概念在本書中前後一通亂翻,只需從前到後按順序學習即可。但一站式學習並不等於傻瓜式學習,有些章節有一定的難度,需要積極思考才能領會。本書可以替你節省時間,但不能替你思考,不要指望像看小說一樣走馬觀花看一遍就能學會。

又是一本C語言書。好吧,為什麼我要學這本書而不是譚浩強或者K&R?

譚浩強的書我就不說什麼了。居然教學生include一個.c檔案。

K&R是公認的世界上最經典的C語言教程,這點毫無疑問。在C標準出台之前,K&R第一版就是事實上的C標準。C89標準出台之後,K&R跟着標準推出了第二版,可惜此後就沒有更新過了,所以不能反映C89之後C語言的發展以及最新的C99標準,本書在這方面做了很多補充。上面我說過了,這本書與其說是講C語言,不如說是以C語言為載體講計算機和操作系統的原理,而K&R就是為了講C語言而講C語言,側重點不同,內容編排也很不相同。K&R寫得非常好,代碼和語言都非常簡潔,但很可惜,只有會C語言的人才懂得欣賞它,K&R是非常不適合入門學習的,尤其不適合零基礎的學生入門學習。

這本書“是什麼”和“不是什麼

本書包括三大部分:

  • C語言入門。介紹基本的C語法,幫助沒有任何編程經驗的讀者理解什麼是程序,怎麼寫程序,培養程序員的思維習慣,找到編程的感覺。前半部分改編自[ThinkCpp]

  • C語言本質。結合計算機和操作系統的原理講解C程序是怎麼編譯、連結、運行的,同時全面介紹C的語法。位運算的章節改編自亞嵌教育林小竹老師的講義,鏈表和二叉樹的章節改編自亞嵌教育朱老師的講義。彙編語言的章節改編自[GroudUp],在該書的最後一章提到,學習編程有兩種Approach,一種是Bottom Up,一種是Top Down,各有優缺點,需要兩者結合起來。所以我編這本書的思路是,第一部分Top Down,第二部分Bottom Up,第三部分可以算填了中間的空隙,三部分全都圍繞C語言展開。

  • Linux系統編程。介紹各種Linux系統函數和內核的工作原理。Socket編程的章節改編自亞嵌教育衛劍釩老師的講義。

這本書定位在入門級,雖然內容很多,但不是一本百科全書,除了C語言基本要講透之外其它內容都不深入,書中列出了很多參考資料,是讀者進一步學習的起點。K&R的第一章是一個Whirlwind Tour,把全書的內容簡單過了一遍,然後再逐個深入進去講解。本書也可以看作是計算機專業課程體系的一個Whirlwind Tour,學習完本書之後有了一個全局觀,再去學習那些參考資料就應該很容易上手了。

為什麼要在Linux平台上學C語言?用Windows學C語言不好嗎?

用Windows還真的是學不好C語言。C語言是一種面向底層的編程語言,要寫好C程序,必須對操作系統的工作原理非常清楚,因為操作系統也是用C寫的,我們用C寫應用程序直接使用操作系統提供的介面。既然你選擇了看這本書,你一定瞭解:Linux是一種開源的操作系統,你有任何疑問都可以從原始碼和文檔中找到答案,即使你看不懂原始碼,也找不到文檔,也很容易找個高手教你,各種郵件列表、新聞組和論壇上從來都不缺樂於助人的高手;而Windows是一種封閉的操作系統,除了微軟的員工別人都看不到它的原始碼,只能通過文檔去猜測它的工作原理,更糟糕的是,微軟向來喜歡藏着揶着,好用的功能留着自己用,而不會寫到文檔裡公開。本書的第一部分在Linux或Windows平台上學習都可以,但第二部分和第三部分介紹了很多Linux操作系統的原理以幫助讀者更深入地理解C語言,只能在Linux平台上學習。

Windows平台上的開發工具往往和各種整合開發環境(IDE,Integrated Development Environment)綁在一起,例如Visual Studio、Eclipse等。使用IDE確實很便捷,但IDE對於初學者絶對不是好東西。微軟喜歡宣揚傻瓜式編程的理念,告訴你用滑鼠拖幾個控件,然後點一個按鈕就可以編譯出程序來,但是真正有用的程序有哪個是這麼拖出來的?很多從Windows平台入門學編程的人,編了好幾年程序,還是隻知道編完程序點一個按鈕就可以跑了,把幾個源檔案拖到一個項目裡就可以編譯到一起了,如果有更複雜的需求他們就傻眼了,因為他們腦子裡只有按鈕、菜單的概念,根本沒有編譯器、連結器、Makefile的概念,甚至連命令行都沒用過,然而這些都是初學編程就應該建立起來的基本概念。另一方面,編譯器、連結器和C語言的語法有密切的關係,不瞭解編譯器、連結器的工作原理,也不可能真正掌握C的語法。所以,IDE並沒有幫助你學習,而是阻礙了你學習,本來要學好C編程只要把語法和編譯命令學會就行了,現在有了IDE,除了學會語法和編譯命令,你還得弄清楚編譯命令和IDE是怎麼整合的,這才算學明白了,本來就很複雜的學習任務被IDE搞得更加複雜了。Linux用戶的使用習慣從來都是以敲命令為主,以滑鼠操作為輔,從學編程的第一天起就要敲命令編譯程序,等到你把這些基本概念都搞清楚了,你覺得哪個IDE好用你再去用,不過到那時候你可能會更喜歡viemacs而不是IDE了。

致謝

本書的寫作得到北京亞嵌教育研究中心的全力支持,尤其感謝李明老師和何家勝老師,沒有公司的支持,我不可能有時間有條件寫這本書,也不可能有機會將這本書公開在網上。

然後要感謝亞嵌教育的歷屆學員和各位老師,在教學和討論過程中我經常會得到有益的啟發,這些都促使這本書更加完善。在本書的寫作過程中,很多讀者為本書提出很有價值的建議,很多建議是熱心網友通過在綫評論提的,有些網友我只知道id或email。都列在下面,排名不分先後。

感謝北京亞嵌教育研究中心的老師們:李明,何家勝,邸海霞,郎鐵山,朱仲濤,廖文江,韓超,吳岳,邢文鵬,何曉龍,林小竹,衛劍釩。

感謝熱心網友:ddd(ddd@clf.net),wuyulei(wuyulei0210@163.com),comma(commapopo@hotmail.com),田偉(sioungiep@zzxy.org),田雨(tianyu_1123@hotmail.com ),daidai(daidai0628@sina.com),鄧楠(monnand@gmail.com),杜樸風(cplusplus@zzxy.org),Zoom.Quiet(zoom.quiet@gmail.com),陳老師(cljcore@gmail.com),楊景(yangbajing@gmail.com),章鈺(buptzhangyu@163.com),chen(cry2133@gmail.com),Jiawei Zhang(rhythm.zhang@gmail.com),waterloo(waterloo2005@gmail.com),張現超(zxqianrong@gmail.com,http://zxqianrong.is-programmer.com/),曾宇(uyucn@163.com),董俊波(dongjunbo@gmail.com),RobinXiang(dancelinux@gmail.com),劉艷明(lonny_liu@hotmail.com),付(been2100@163.com),cleverd(crossie@qq.com),orange(juicerococo@hotmail.com),徐斌(simlink_xub@163.com),cyy(cyy198767@hotmail.com),Linux_Xfce(coodycody23@gmail.com),馮海雲(906702745@qq.com),侯延祥(houyx2008@163.com),churchmice(firefoxelectric@gmail.com),linux——00xx00xxooxx(codycody23@gmail.com),syfeagle(syfeagle@hotmail.com),王公僕(wanggongpu@gmail.com),劉敏(liuminchinese@163.com),Laciq(dd@qq.com)。

在寫作過程中我遇到過很多困難,工作繁忙,對未來迷茫,生活壓力大,缺乏安全感,個人瑣事等等。然而有這麼多熱心的同學、老師、朋友、網友在等着看我的書更新,給我提建議希望我把書改得更完善,這是我堅持寫下去的最大的動力。謝謝你們!

最後幾句話

和大多數作者一樣,最後我要說的是我水平十分有限,沒寫過C編譯器和C標準庫,我不能保證書中的內容全部正確,如有錯誤歡迎批評指正。遺憾的是很多作者把這句話當成了擋箭牌,當成了自己不必竭盡全力保證內容正確性的藉口。寫書是一件嚴肅的事,書中的錯誤所有人都看得見,白紙黑字賴不掉的。我教過的很多學生都在大學裡學過C語言,甚至考過二級,但程序寫得一塌糊塗,連最基本的概念都搞錯了,以前學過的C語言教材中的錯誤在他們腦子里根深蒂固,即使我糾正多次,他們仍然只記得以前學過的錯誤概念,這種有基礎的學生還不如沒有任何基礎的學生教起來容易。我非常害怕我教給別人的仍然是錯的,所以我仔細研究了C99之後才敢動筆寫書。這本書涵蓋的話題比較廣泛,我竭盡全力也不足以保證書中的內容全部正確,還要依靠社區的力量一起來完善這本書,這樣才能真正對讀者負責,所以我選擇將這本書開源。

希望本書成為你求學道路上的第一個夥伴。

宋勁杉 北京 2008年11月27日