趣談程式設計史第2期-這個世界缺少對C語言的敬畏,你不瞭解的C語言科普
阿新 • • 發佈:2020-01-16
這是我製作的程式語言科普系列視訊的第二期,部落格根據視訊文案整理而成,提供給有需要的朋友閱讀或使用. 視訊地址:https://www.bilibili.com/video/av83627932/ 如果感興趣觀看視訊,感謝博友.在華夏文明的歷史長卷中, 曾經有一段狼煙四起,群雄逐鹿的特殊歷史時期 史稱春秋戰國 這段時期,諸侯分裂,各自為戰,哀鴻遍野,戰火連天 貧苦人民生活在水深火熱之中 最終秦國招賢納士,積極變法 奮六世之餘烈 席捲八荒 一統天下 最終結束了這段混亂的時期, 並且統一了文字,貨幣,語言等等 開創了華夏文明一個嶄新的篇章 在程式語言的發展歷史中 也有這樣一段混亂不堪的時期 這段時期, 在各大公司生產的不同機器上,都搭載著自家獨有的組合語言 而組合語言和機器綁的死死的,不能通用 這使得不同機器,不同系統之間的交流變得異常困難 此時還沒有出現能夠相容不同機器的程式語言 這極大地阻礙了計算機的發展 後來經過多方努力,終於出現了一個通用且於計算機無關的程式設計語言標準 在這個標準下孕育出的最耀眼的一顆明星 也是目前應用最廣泛,影響最深遠的程式語言 他就是今天的主人公,C語言 魯迅先生曾經說過 程式設計不會C語言,便稱英雄也枉然 這期視訊我將帶你追溯C語言的誕生和發展歷史 瞭解C語言和以java為代表的程式語言之間的優劣 盤點C語言讓人又愛又恨的特性 以及分析C語言為何能穿越時空,長盛不衰 這些都是過程, 我的最終目的是希望 那些曾和C語言淡淡交匯,又天各一方的朋友 能夠對C語言的有一些重新的認識和一點點敬畏 給你和C語言的關係畫上一個圓滿的感嘆號 因為據我觀察周圍的朋友對C語言的態度 滿滿的都是恐懼和誤解 我覺得這個世界缺少對C語言的敬畏 這是程式語言專題科普系列的第二期 建議你先看第一期,不看的話也沒關係, 這是個單元劇,不是連續劇 下面的免責宣言我會連說三期 視訊的定位是輕科普,我預設這個視訊的觀眾都是編外人員 我希望用一種有趣下飯的方式能讓你在吃著火鍋唱著歌的間隙 快速瞭解一些網際網路相關的專業術語和行業趣聞 有勸退門檻的程式設計知識 我會小心繞過 實在繞不過去我就降維解釋 同時我單方面宣佈你們也預設這個視訊的製作者是一個娛樂up主 程式設計專題的科普在專業和趣味性上很難把握平衡 在內容不出現滑鐵盧的前提下 我還是會盡量追求趣味性 而且 我也不是一個資深C程式設計師 如果你剛好是一個C語言大神 希望你能抱著微服私訪的心態來觀看本期視訊 就當是到基層來與民同樂吧 能點進來看的朋友肯定或多或少的知道C語言這麼個東西 因為現在很多大學的非計算機專業,也會開一門課,叫C語言. 凡是學過的都知道 C語言 那真不是個東西 譚浩強這個名字是不是我一提就讓在座的諸位虎軀一震 不由的想起當年被C語言支配的恐懼 多少品學兼優,德智體美勞全面發展的好學生 在面對C語言時都突然感覺被制裁了 據我觀察 學過C的編外同學大學畢業後很多並不知道自己能幹什麼 但基本都表示 程式設計 我不行 其實真實情況是,別說編外人員, 小弟我作為正規軍 當年在霍格沃茲學C語言的時候也差點當了逃兵 記得那還是2012年大一的第一堂C語言課 #include <stdio.h>” 這一坨東西的出現讓我的人生提前進入了世界末日 那時候真是 感到萬飛沮喪,甚至開始懷疑人生 我就親眼見過上了兩次C語言的課就神祕失蹤的同學, 真是程式設計一入深似海,從此君王不早朝 但是 我沒有放棄 每一次 我都在徘徊孤單中堅強 後來 經過軟磨硬泡的攻堅戰 我終於靈光乍現 豁然開朗 在完成一個變態的程式設計題目後 我覺得 這個門 我算是入了 我想對所有被渣C傷害過的朋友說 大學沒學好C語言 不是我們的問題 是大學老師的問題 譚浩強的問題 在介紹C語言的歷史前,我們需要先簡單回顧一下程式語言的進化之路 程式語言總體上經歷了 從機器語言到組合語言,再到高階語言的進化. 高階語言又可以細分為面向過程和麵向物件兩種 面向物件的代言人暫時頒發給上期的java 而面向過程的門面當仁不讓的要留給本期的主人公C語言 在人和計算機兩者之間,最靠近計算機的就是機器語言, 因為計算機的電路元件 輸入輸出只有高低電平,只能表示0和1兩個數,也就是二進位制 機器語言就是0101二進位制的一個指令集合, 它是計算機能識別的語言,機器語言是所有程式語言的歸宿 不管你是多麼花裡胡哨最終都將被轉化為機器語言執行 在遠古洪荒時期,用紙帶打孔通過紙帶機輸入計算機 交給計算機執行,那可是程式設計師必備技能 但是0101這東西門檻實在太高了,因為看不懂啊,不光別人看不懂,自己也看不懂 當程式設計師寫完的一段機器語言,執行沒問題的時候, 此時世界上就只有程式設計師和計算機能懂, 等程式設計師吃個午飯回來,就只剩計算機能懂了. 後來聰明的程式設計師定義了一個規則,比如加法指令是00000011,直接對映為ADD, 這下大家都能看懂了.這個就叫組合語言, 組合語言的出現大大的降低了程式設計的門檻,這是第二代程式語言 後來懶惰的程式設計師又再一次對組合語言進行改造, 比如把加法指令ADD,直接對映為+號, 把多個複雜的彙編指令,直接用一個語法關鍵字來定義. 這樣門檻就更低了,這就是高階語言. 這就要講到C語言了. 嚴格來說,高階語言的鼻祖並不是C語言, 但如果所有的程式語言匯聚一堂拍一個大合照, 你要問前排最中間的位置讓誰坐 我想在場的諸位選擇應該出奇的一致 都選C 根據本視訊剛剛釋出的程式語言榜中榜的排名來看 C語言目前是世界排名第三的語言 好奇的朋友可能要問了,那前兩名是誰呢 聰明的朋友一眼就看出來了,那一定是A語言和B語言 這位朋友不簡單,還真讓你蒙對了,我們就要從A語言開始說起 讓我們把時鐘撥回到上世紀 50年代末期,組合語言開始出現 由於彙編是一種面向機器的程式語言 它能直接訪問和控制硬體,比如儲存器,CPU 執行效率很高 接近於機器語言的水平 同時又比較容易被人理解 因此在當時的市場上大放異彩 但是有個很頭疼的問題 不同廠家的CPU都有自己的一套專屬的指令集, 這就使得組合語言沒法在不同型別的裝置上進行移植 不同機器之間的交流也更是遙不可及 1958年,德國的GAMM組織和ACM組織聯合釋出了一個 通用並且和計算機解耦的程式語言設計規範, 名叫 ALGOL, 這就是我們笑稱的A語言,其實沒有這樣一個官方的叫法 1963年,英國的劍橋大學基於ALGOL60的規範推出了CPL語言 後來又對CPL語言做了一些簡化和重新設計,推出了BCPL 關於組合語言介紹兩種 目前還活躍在我們視野中的組合語言,大概有以下幾種 比如8086彙編,win32彙編,win64彙編,AT&T彙編,ARM彙編等等 我們簡單介紹兩個 你可能聽過一個詞 X86 8086彙編最早是英特爾公司推出的搭載在8086處理器上的操作指令集 後來英特爾推出了好幾款86結尾的處理器, 統稱為x86架構 內行的朋友已經知道我第二個要說的是誰了 AT&T彙編,之所以說它,就是要引出AT&T公司 AT&T全稱是 美國電視電話公司,創始人貝爾,就是電話的發明者 公司旗下有一個聲名遠揚的研究部門,也就是貝爾實驗室 像電晶體,二極體,太陽能電池,交換機,通訊衛星等等等等很多重大發明都出自 貝爾實驗室之手,包括後面要說的C語言和Unix作業系統 總之,貝爾實驗室是人類智慧精華的傑出代表 在1964年,貝爾實驗室和通用電氣以及麻省理工合作了一個專案, 給當時的大型主機開發一套多使用者,多工,能7*24小時執行的分時作業系統, 簡稱 multics, 我們的第一個主人公, 在貝爾實驗室任職的KenThompson就加入了該專案 這個專案耗資巨大,但是進度緩慢, 後來幾經波折,最終因為資金短缺,以及系統性能不盡人意等種種原因 於1969年宣佈破產,貝爾實驗室黯然退出 Thompson不僅是彙編大牛也是個遊戲狂人, 在開發Multics系統期間, 他用摸魚的時間在Multics系統上開發了一款叫"space travel"遊戲 貝爾實驗室退出以後,連同機器也被部門裝箱運走了 專案可以流產,遊戲不能打烊 湯普森最後在貝爾實驗室的庫房裡找到一臺老式PDP-7的機器, 不是GDP 也不是PDD 是一個連作業系統都沒有的古董裸機 沒有作業系統就沒法運行遊戲 那咋辦 寫一個吧 KenThompson是個狠人啊, 他只用一個月就用PDP的組合語言完成了新作業系統的開發 平均起來差不多 一週一個核心,一週一個檔案系統, 一週一個編輯器,一週一個編譯器, 使用匯編語言編寫的作業系統因為和硬體耦合嚴重移植困難 後來他改進BCPL,移除了一些自己認為不需要的元件, 又加上了自己的一些程式設計習慣,開發出了B語言,以BCPL的首字母命名 並且使用B語言重寫了這個新的作業系統,取名為UNIX 聽到這你是不是很想跟我們的主人公湯普森喊一聲湯神,或者是佛祖 為了加深你的記憶 我後面就叫他湯神 Unix面世初期 並沒有掀起太大波瀾 但是引起了湯神的同事,DennisRitchie的興趣 我們第二個主人公, 也欣然加入到改造Unix系統的隊伍中 至此,雙劍合璧,一場轟轟烈烈的Unix革命拉開了序幕 1972年 他們把Unix系統移植到當時的最先進的大型機PDP-2上 由於Unix系統的簡潔穩定和高效 Unix喧賓奪主,代替了當時PDP2上自帶的DEC作業系統 1973年十月,在IBM舉辦的作業系統專題研討會上 KD兩兄弟做了Unix的宣講並且展示了Unix系統, 引發了整個會場的轟動,大家紛紛湧上來索取Unix系統程式 Unix得到了廣泛的應用 B語言是一種無資料型別的語言,這使得程式無法方便的訪問字元型別, 裡奇對B語言就進行了大刀闊斧的改良 比如引入資料型別的概念,最終演化為一個新的程式語言 起初準備把這個新語言命名為NB,意思是new B 可能裡奇也覺得新語言太過牛掰,超前,比new B 還是new 於是以BCPL的第二個字母命名了這個新語言 也是在1973年,C語言終於登上歷史舞臺了 他來了 他來了 他腳踏祥雲走來了 C語言和舊版的Unix發生了完美的化學反應 隨著Unix系統摧枯拉朽般席捲市場 至此一個簡潔高效優雅可移植的Unix終於在千呼萬喚中黃袍加身 C語言一躍成為當時程式語言屆最閃耀的一顆明星 1978年,那是一個春天,在希望的田野上,裡奇正式出版了 曠世名著<C程式語言>,被稱作C語言的聖經 1982年 ,美國國家標準協會聯合一眾有志之士,成立了C標準委員會, 從1989年至今,委員會發布了多個C語言標準,為C語言的進化和健康發展做出了很大貢獻. 1983年,湯普森和裡奇攜手獲得美國計算機協會頒發的圖靈獎 ,圖靈獎被稱作是計算機界的諾貝爾獎,象徵著計算機領域最崇高的榮耀 2011年,C語言之父,Unix之父,達尼斯*裡奇去世,享年70歲, 讓人感慨的是,裡奇並不被世人所熟知 當時並沒有引起這個世界的太大的波瀾 我們都知道,同一年,喬布斯也因為癌症去世,和裡奇僅僅相隔幾天而已 全世界在那一天都陷入悲傷的氛圍 裡奇去世後,計算機歷史學家Paul E. Ceruzzi說 裡奇不被人們知道。他的名字一點也不家喻戶曉,但是…… 如果你有一臺顯微鏡,能在電腦裡看到他的作品,你會發現裡面到處都是他的作品 麻省理工大學計算機系的馬丁教授說: 如果說,喬布斯是視覺化產品中的國王 那麼裡奇就是不可見王國中的君主 喬布斯的貢獻在於,他如此瞭解使用者的需求和渴求 以至於創造出了讓當代人樂不思蜀的科技產品 然而,卻是裡奇先生為這些產品提供了最核心的部件 人們看不到這些部件,卻每天都在使用著 接下來 我們聊一點乾貨 C語言有兩個地方讓人又愛又恨,那就是指標和記憶體管理 指標是一個很特殊的變數,並不用來存資料, 而是專門用來存放地址, 這個地址需要在記憶體中申請空間才能裝東西 是不是完全聽不懂這人在逼逼什麼 對很多C語言小白來說,這個指標指著指著就指向了沮喪,奔潰,甚至放棄, 很多人覺得指標的設計很反人類,甚至弊大於利 我冥思苦想了很久想到一個不太恰當但有助於外行理解的比喻 同學 你玩遊戲嗎 如果玩 你玩過英雄聯盟嗎 如果玩過 你知道大魔王Faker嗎 如果知道 你見過Faker切屏嗎 如果把遊戲地圖當做你的整塊實體記憶體 顯示器上展示的遊戲畫面相當於指標指向了其中的一小塊記憶體空間 當你切屏時就是移動了指標,指向了另一塊記憶體空間 faker的光速切屏能讓他在對線的同時洞悉整個遊戲的戰況 這放在C語言中就是能把指標整出花活的程式設計高手 指標的存在讓程式設計師可以直接操作實體記憶體, 如果玩的溜,可以寫出緊緻高效的程式碼, 同時也給程式設計師提供了很大的空間來發揮你天馬行空的想象力, 如果你掌握了指標,對C語言那就是四個字,愛了愛了 如果卡死在指標這裡,多半你就只能感嘆,來不了來不了 第二個讓人詬病的就是記憶體清理 C語言沒有垃圾回收的機制 則意味著你需要手動且及時的清理調不需要的資料, 否則會造成記憶體溢位,就是記憶體不夠用了, 目前江湖上流傳比較廣的一個段子是這麼說的 去食堂吃飯,吃完飯就走的是java程式設計師, 吃完飯還要自己收拾的就是C程式設計師 這個其實說的就是垃圾回收的問題 我也想到一個比喻你可以同時理解指標和垃圾回收機制 試想你是一個富婆,你擁有一個100平的衣帽間, 你可以隨心所欲的放置你的衣服,鞋和化妝品, 你能準確的找到每一個物品的擺放位置 你想要帶走什麼東西也可以直接推門進去,拿完就走,簡單粗暴 你想扔掉不需要的東西也是順手的事情. 這就是C語言 試想你是一個富婆中的富婆,不僅擁有100平的衣帽間,還專門僱了一個保姆守在守在門口聽你差遣 你買的東西直接扔給保姆,她會幫你寄存, 東西放滿了保姆需要小心翼翼的挨個判斷哪些物品是你從來沒用過的幫你扔掉, 你想要什麼東西就站在門口吩咐她去拿 這就是java 這樣你其實是省事了,但會帶來兩個問題 第一你要額外花錢僱傭這個保姆,還要騰出一塊地分配給他 第二你在放和取這件事上會消耗額外的時間,本來一個人就能幹的人現在需要兩個人,效率就變低了 所以C程式設計師,面對java程式設計師會有一種優越感, 覺得後者寫的程式碼是沒有靈魂的. 如果你不是程式設計師,我猜你可能會說,道理我都懂, 但我還是想吃完飯就走,而且是而且開著我的手動擋 其實這個想法很對 如果記憶體足夠大,運算能力足夠強,能夠接受這個額外的開銷 後者也不失為一個更好的方式 這也是java等語言廣受歡迎的一個很重要的原因 將複雜的指標封裝成引用的概念,同時提供自動垃圾回收的機制 正是當前新興程式語言都在做的事情 C語言和java都屬於高階語言 C語言離計算機底層更近屬於高階語言中的低階語言 以java為代表一眾語言都是參考了C的設計,將很多東西封裝起來 以更接近於人類的思維來提供語法和功能,他離計算機底層更遠 也不用糾結這樣編碼是不是沒有靈魂 當你給你喜歡的姑娘發微信時, 你知道在應用層發生了什麼, 網路層發生了什麼 資料鏈路層發生了什麼 資料包經過了多少個節點 多少次路由 才最終跨過山河大海達到對方的手機, 你們關心過嗎,不,你們沒有, 你們關心的只有對方有沒有回覆 程式設計師也是如此 程式語言的發展之路也是程式設計師離計算機底層越來越遠的道路 關於垃圾回收,我們聽聽湯神本人是怎麼說的 在程式設計人生一書中,Seibel就向湯神提了一個這樣的問題 你怎麼看待垃圾收集 java已最終將垃圾收集技術融入主流語言 這究竟是好是壞,這種技術是否應該成為主流 湯神回答說, 對這個話題,我有完全相反的兩個答案,如果你正在編寫作業系統 或者C語言的編譯期,或者是會被很多很多人使用的東西 我認為垃圾收集多半是一個錯誤的選擇 用它是自欺欺人,因為你完全可以手動去做,而且效果要好的多 用它無異於毀了你的任務,你的工作,讓你的使用者用起來更慢 那根本不適合作業系統 但如果你在編寫一個簡單程式,完成一個小任務,有了答案編將程式扔掉 那是很棒的,他剔除了一層你並不想深究的東西,這個代價你可以接收 計算機是如此之快,使用它可以達成一個多方共贏的局面 現在已經是個效能過剩的時代,因此讓java這樣的語言大行其道 但是在上世紀可沒有這麼好的硬體資源給你造, 對效能的追求是一種"極客"精神的體現 這也是屬於C語言驕傲的倔強 海闊憑魚躍,天高任鳥飛 C語言可以說是目前應用最廣泛,影響最深遠的程式語言. 在各個領域都大放異彩. 市面上幾乎所有的編譯器,底層都是由C語言實現, 包括java,Python,ruby等等 市面上幾乎所有的作業系統核心, 底層都是由C語言實現,包括你的手機平板筆記本. 還有各種驅動,嵌入式裝置,微控制器 在這方面上,其他程式語言,有一個算一個 都得認慫 程式語言一條街 打聽打聽誰是爹 不僅如此,由於C語言很多特性尤其是集大成者的指標 極端一點,我甚至可以這麼說 上至九天攬月,下到五洋捉鱉 只有你想不到,沒有C語言做不到 雖然我對C語言有崇高的敬意 但如果你是一個程式設計的小白, 沒有經過計算機基礎學科的滋養 並且正在考慮學習一門程式語言 作為過來人,我個人並不建議你上來就學C語言 我甚至覺得 大學專業都不應該在大一安排C語言的課程 我懷疑開這個課就是為了讓你們不要誤入歧途 學C語言有個現象 學會了的人太健忘 沒有學會的人又太懵懂 這就導致了 不會的人去問大神C語言為什麼這麼難 會有無數的聲音告訴你 我覺得C語言很好學啊,語法簡單,比Java容易多了 言外之意就是 哦 你不會啊 那你怕不是個智障吧 C語言的指標,回撥,遞迴等等都需要耗費很大的心力去攻克 花花世界,有很多簡單易學的程式語言楚楚待撩 捏軟柿子並不丟人 人生苦難 你懂我意思吧 當然以上只是我個人的觀點 跟我本人無關 既然C語言這麼重要 你可能要問 如果沒有C語言,整個網際網路體系豈不是盡失半壁江山, 這麼同學,你這種危言聳聽的想法確實是有點保守了 小弟認為,如果沒有C語言,整個網際網路體系會瞬間崩塌 C語言就像是河流發源地的一眼清泉 出生於極寒之地,成長在崎嶇山間 奔跑在時間的長河裡,不斷匯聚能量,開枝散葉 不僅孕育出了眾多的程式語言 也驅動著網際網路這座巨輪劈波斬浪,無畏前行 說C語言供養著現代商業文明體系也不為過 如今在各個領域已經有很多年輕有為的程式語言脫穎而出, 聲勢浩大,雄踞一方 面對著飛速發展的時代和一眾躍躍欲試的小鮮肉語言 C語言這個鋼鐵直男已經開始退居幕後 但是這並不意味著底層離社會發展會越來越遠 恰恰相關 這會讓C語言的作用更加重要 底層的世界依然是廣闊天地,大有作為 當我們面對只有簡陋硬體,需要極致效能, 或者一些其他語言都束手無策的場景時 它總是能及時站出來,輕描淡寫的說 穩住別送 這把我C 當大家開啟由C語言實現了核心的Windows或Mac作業系統 操作著由C語言實現了驅動的鍵盤和滑鼠 使用著由C語言實現了底層的網路通訊協議 和網友討論誰是世界上最好的程式語言時 C語言只是微微一笑,便默不作聲 繼續向前奔流 當我們追溯程式語言的歷史時,C語言是一座無法繞過的豐碑 牛頓站在了巨人的肩膀上, 如今,我們都站在C語言的肩膀上 作為程式語言界的元老成員, C語言生於舊社會,長在紅旗下 走在春風裡,準備跨世紀 當然,是下一個世紀, 我們都知道C語言不會死,他的熱血依然滾燙 而它的歸宿就在前方 那就是星辰大海