誕生50年的C語言為何穩(wěn)如泰山?

導讀:計算機專業(yè)的“普通話”。
作者:木羊同學
來源:華章計算機(ID:hzbook_jsj)

C語言是個很有意思的話題。對于計算機專業(yè)的學生來說,C語言可以算是本專業(yè)的另一門“普通話”。曾經(jīng)看過一份資料,說國內(nèi)九成高校在給大一開設的“高級編程語言”一課中選擇使用C語言,而這僅僅只是開始。
我們知道,計算機專業(yè)是有幾門“硬菜”課程的,比如說數(shù)據(jù)結(jié)構(gòu)、算法、編譯原理和操作系統(tǒng),這些課程都有自己的知識體系,不過,所使用的教材很可能會在書名后面多加一個括號寫上“C語言描述”,這是因為計算機專業(yè)的知識總是需要通過編程才能落地見效,而教材們都喜歡選擇用C語言來示例編程。
可以說,計算機的專業(yè)課基本上就是個C語言宇宙,哪怕是畢業(yè)多年以后重聚,說一句“Long time no C”,一定都能引得大家會心一笑和無限回憶。
不過,疑惑隨之而來。前兩年一位985的學生在網(wǎng)上發(fā)帖詢問:為什么現(xiàn)在學校還在教授C語言,而不選擇更為“現(xiàn)代”的Java或者Python?這貼很快變成圈內(nèi)熱帖,大家一時議論紛紛。在很多人看來,誕生于1973年的C語言雖然歷史地位無法撼動,但已經(jīng)是一款爺爺輩的老語言,早就該到了“尚能飯否”的年紀。
那么,應該學什么呢?在20年前互聯(lián)網(wǎng)剛剛興起的時候,大家都想去學更時髦的Java,而到了機器學習大紅大紫的現(xiàn)在,則很難拒絕Python的誘惑。近幾年Rust、Go、Swift等新語言像雨后春筍般冒出來,隔一段時間就來一版重大更新,變著花樣在刺激著大家喜新厭舊的神經(jīng)。所以,每隔一段時間網(wǎng)上就會掀起一陣“是時候要換掉C語言”的討論。
不過,C語言真的已經(jīng)是時代的眼淚了嗎?
01 穩(wěn)如泰山的C語言
大家都知道的是,當下很多主流的編程語言,其實都和C語言有著緊密的血緣關(guān)系,C++就是C語言加上面向?qū)ο螅珻++--又派生出了Java,至于受C++和Java影響而派生的語言又不知道有多少,真可謂一生二、二生三、三生萬物。不過,也許大家并不了解,雖然C語言兒孫滿堂,但自身還正處在當打之年,和子孫同臺競技不落半點下風。
TIOBE是業(yè)內(nèi)知名的編程語言排行榜,我查了一下最近20年的排名記錄,驚訝地發(fā)現(xiàn)雖然各色編程語言一直在TIOBE上你方唱罷我登場,但是C語言始終穩(wěn)如老狗,一直像釘子一樣釘在前2位置霸榜,不時還偷摸一把排名第一的寶座。近幾年P(guān)ython乘著機器學習的東風從一個勝利走向另一個勝利,最近更是成功把Java從王座上請了下來,然而回頭一看,發(fā)現(xiàn)排在第二的居然還是C語言。
這就很有意思了。也許有人會認為,這是因為C語言占了時間悠久的便宜,歷史上積累下來的代碼量大,所以比重就大。不過,TIOBE是綜合了全球在搜索引擎中的搜索次數(shù)、各類課程的使用次數(shù),以及業(yè)內(nèi)資深專家和廠商的使用偏好等等因素綜合計算給出的排名結(jié)果,反映的是編程語言在全球的熱度,而不是機械地比較代碼量。
從TIOBE的排名可以看出,不僅僅是國內(nèi)高校,即使放眼全球的教育界和工業(yè)界,C語言都仍然是穩(wěn)穩(wěn)當當?shù)睦洗蟾纭?/span>
不過,編程語言領域早就卷得一塌糊涂,為什么一款誕生了50年的編程語言居然還能傲視群雄,其中是不是有什么成功的秘密呢?
02 成功的秘密
在我看來,C語言最大的成功就是準確卡位。C語言有一本當之無愧的經(jīng)典之作,叫作《The C Programming Language》,機工華章出了中文版,譯為《C程序設計語言》,作者是B.W.Kernighan和D.M.Ritchie,也稱為K&R,而其中的R——D.M.Ritchie正是C語言的作者。
《C程序設計語言》不但是C語言的經(jīng)典教材,還是教材的教材,大家都在通過這本書學習怎么寫教材,我們學習新語言都會從打印“hello,world”開始,這個傳統(tǒng)就是起源于這本書。
《C程序設計語言》談到了C語言的優(yōu)勢,說:C語言是一種通用的程序設計語言,既不“高級”也不龐大,它與UNIX系統(tǒng)關(guān)系密切,但并不受限于任何一種操作系統(tǒng)或機器,很適合用來編寫編譯器和操作系統(tǒng),因此被稱為“系統(tǒng)編程語言”。
C語言的秘密就藏在這句“既不‘高級’也不龐大”里面。這里的“高級”并不是指編程語言的水平高低,而是相對于底層硬件的抽象,越高級的編程語言,會越模糊底層的硬件細節(jié)。
C語言雖然經(jīng)常用于教授“高級編程語言”這門課,但既不是第一款高級編程語言,也不是最高級的編程語言。
C語言借鑒了BCPL語言的很多概念,而BCPL語言本身比C語言還要高級一點。BCPL語言注重的是算法,并沒有設置“類型”這一概念,也即我們在C語言里面十分熟悉的字符、整型和浮點型這些類型,在BCPL語言都是沒有的。我曾經(jīng)出于好奇找過BCPL的代碼來看,感覺這種盡量剝離底層硬件細節(jié)的編程語言寫起來更像是偽代碼。
其實,很多現(xiàn)代編程語言也在淡化類型這一概念,Python一類的動態(tài)語言使用的是“鴨子類型”,不用顯示聲明變量類型,而傳統(tǒng)強類型的靜態(tài)語言則選擇了“類型推斷”來曲線救國,相比之下,強調(diào)類型的C語言就要低級得多。
不過,低級有低級的好處,C語言設計的類型并非憑空生造,而是對底層硬件的概括描述,尤為適合精準地操縱計算機底層硬件。我們寫操作系統(tǒng)、寫驅(qū)動、寫單片機、或者寫一些想要榨干硬件性能的程序,就必須選擇這種能夠看到底層硬件細節(jié)的編程語言。
有人會說,匯編也是低級語言,也能操縱硬件,也能看到硬件細節(jié),甚至能看到更多的硬件細節(jié),為什么不選擇匯編呢?這是因為C語言比匯編又高級一點,在開發(fā)效率和開發(fā)體驗方面是降維打擊。
正是因為C語言比低級語言要高級一點,又比高級語言要低一點,在一眾編程語言中硬生生地開辟出叫“系統(tǒng)編程語言”的生態(tài)位。這是個很特殊的生態(tài)位,IT生態(tài)越是枝繁葉茂,面向應用開發(fā)的高級編程語言競爭越是激烈,系統(tǒng)編程語言的地位就越重要越穩(wěn)固。
也許又有人會說,能不能用Java和Python這些更現(xiàn)代的編程語言干系統(tǒng)編程語言的活呢?很難。C語言中有一個讓所有人既愛又恨的語言特性,叫做指針。指針很神奇,它很靈活,也是個小惡魔,很多開發(fā)者把C語言稱作“災難”,那么災難的源頭就是指針。
所以,當初Java推出來的時候,就把干掉指針作為其中一個重要賣點。靈活和安全是一對矛盾體,主流的開發(fā)語言都選擇了犧牲靈活性來提升安全性,當然代價也就是不再可能染指系統(tǒng)編程語言這一生態(tài)位了。
最后說一說C++。大家都覺得C++是應該接了C語言的班的,畢竟C++從名字上看就是C語言的plus升級版,C語言能干的C++也能干,還提供了一眾C語言所不具備的高級語言特性,正所謂“飛龍騎臉怎么輸”。
但是,C++究竟還是輸了,究其原因,也許是C++堆疊了太多的優(yōu)秀功能,反而變得過于臃腫,大家紛紛表示里面水太深根本把握不住,于是優(yōu)勢成了劣勢,紛紛選擇回歸了并不龐大的C語言。
03 不斷進化
提升軟件開發(fā)能力當然很重要,想要熟悉主流的編程語言無可厚非。不過,軟件開發(fā)并非只是編程,而對于計算機專業(yè)來說,軟件開發(fā)也遠非全部內(nèi)容,全面地理解計算機體系結(jié)構(gòu)也許更符合這個專業(yè)的教學目的。從這個角度來看,準確卡位的C語言確實比Java和Python更為適合。
不過,C語言也并不是靠精準卡位的老本吃到了現(xiàn)在。在閱讀C語言的相關(guān)文獻時,有時會看到C89、C99、C11、C2x之類的神秘數(shù)字,譬如說Linux內(nèi)核在從C89向C11遷移中取得了一些進展,又譬如說Visual Studio 開始支持C11 和 C17 。這些神秘數(shù)字正是C語言在不斷進化的證據(jù)。
C語言誕生于50年前,無論設計在當時來說多么精妙,經(jīng)歷了如此漫長的時間跨度以后,肯定都會積累巨量的改進需求。一成不變肯定會被時代淘汰,但放任讓各家C語言編譯器廠商自行改進,結(jié)果可能是出現(xiàn)一堆都自稱是C語言但無法互通代碼的C語言實例。
C語言早就看到了這個問題,早在1983年美國國家標準協(xié)會(ANSI)就成了專門的委員會來制定一個“無歧義的、與具體機器無關(guān)的C語言定義”,也就是C語言標準,通常稱為“ANSI C”。
ANSI C到目前為止發(fā)布了三個重要版本,分別是C89、C99和C11。1989年發(fā)布了第一版ANSI C,這就是C89。隨后,C語言在C99和C11中又引入了一些新的功能和語言特性。目前最新的ANSI C是2018年發(fā)布的C17,不過并沒有加入新的功能和語言特性,只是對C11進行補充完善。C2x是下一個ANSIC,又會給C語言帶來一些新的特性,社區(qū)都特別期待,有消息說C2x可能就在2022年年內(nèi)發(fā)布。
D. M. Ritchie老爺子已經(jīng)在2011年去世了,但C語言并沒有放慢進化的腳步,正不斷通過更新ANSI C來變得更為現(xiàn)代化。前面提到說C++是C語言的plus升級版,這個說法流傳很廣,但其實并不十分準確。C++誕生于1979年,在那個時間節(jié)點上C++確實是C語言的plus升級版。
但隨著C語言自身也在不斷演化,現(xiàn)代的C語言和C++的關(guān)系其實更像是一個藤上結(jié)出來的兩個不同的瓜。ANSI C是前向兼容的,不過,想要享受C語言不斷進化帶來的便利,就要不斷學習新的語法。
最后推薦幾本學習C語言的書。K&R那本經(jīng)典著作《C程序設計語言》是學習C語言的必讀書,這本書和C語言的設計思路是一樣的,用不太多的篇幅把重點都介紹了。我知道大家在學校里都用另一本書,不過很多人看完都說,早知道就應該先看《C程序設計語言》。
接著當然是要用C語言寫點算法和數(shù)據(jù)結(jié)構(gòu),這部分推薦閱讀《C語言編程思想與方法》,這本書兼顧了介紹語言特性和分析解題思路,適合上手練習。
要了解C語言改進的內(nèi)容,可以讀一讀《現(xiàn)代C:概念剖析和編程實踐》,已經(jīng)用到了最新的C17。這本書比較硬核,建議對C語言有了一定編程經(jīng)驗以后再讀會大有裨益。
關(guān)于作者:莫凡? ,網(wǎng)名木羊同學。娛樂向機器學習解說選手,《機器學習算法的數(shù)學解析與Python實現(xiàn)》作者,前沿技術(shù)發(fā)展觀潮者,擅長高冷技術(shù)的“白菜化”解說,微信公眾號“睡前機器學習”,個人知乎號“木羊”。

延伸閱讀??

《C程序設計語言(第2版·新版)典藏版》
推薦語:C語言的設計者之一Dennis M.Ritchie 和著名的計算機科學家 Brian W.Kernighan合著的介紹C語言的權(quán)威經(jīng)典著作。我們現(xiàn)在見到的大量論述C語言程序設計的教材和專著均以此書為藍本。原著第1版中介紹的C語言成為后來廣泛使用的C語言版本—標準C的基礎。人們熟知的“hello,world”程序就是由本書首次引入的,現(xiàn)在,這一程序已經(jīng)成為所有程序設計語言入門的第一課。
??

《C語言編程思想與方法》
聚焦編程的思路和方法
帶你掌握C語言程序設計的精髓
131個經(jīng)典問題求解示例
全面覆蓋C語言編程中需要深入理解的知識
推薦語:本書重點講解編程的思路和方法,以及在C語言編程中需要深入理解和掌握的知識,通過大量的示例展示這些方法和知識的運用方式,以期有助于讀者養(yǎng)成專業(yè)化的編程習慣,提高專業(yè)化的編程能力。本書從增強讀者的感性認識入手,循序漸進地引入專業(yè)化編程所需要的知識。本書的內(nèi)容涵蓋了從語言細節(jié)到實際運用多個層面。通過對示例的多角度分析,示范對關(guān)鍵知識和技術(shù)的運用;通過對關(guān)鍵內(nèi)容在不同層次上的適當重復,幫助讀者深化對概念的理解和掌握。
??

《現(xiàn)代C:概念剖析和編程實踐》
C語言學習利器
按讀者對C語言的認識組織內(nèi)容
進可精通,退可鞏固
推薦語:作為一種有50年歷史的編程語言,C語言還是非?,F(xiàn)代的。無論是編寫嵌入式代碼、低級系統(tǒng)例程,還是高性能應用程序,C語言都能應對挑戰(zhàn)。本書基于新的C標準,從現(xiàn)代視角,深刻剖析了這種久經(jīng)考驗的語言的概念及實踐應用。
