學會了 C 語言真的可以開發出很多東西嗎?

2021-02-13 技術實驗室

偶然間看到知乎的這個帖子,想起當初剛開始學C時候的自己,真的覺得這篇文章寫得非常好。

作為一個沒有經驗的大一學生,C語言是接觸的第一門程式語言。當時只能寫一些標準C的程序,就是運行在黑框框裡面的那種。直到後來接觸了Windows API 才知道原來C語言這麼強大,可以做這麼多事。

馬裡奧碰到花朵就變身。

什麼是馬裡奧?一個裝著 16 × 32 個小色塊的長方形,其中一些色塊填著顏色,另一些沒有。什麼是花?一個 16 × 16 的正方形。什麼是「變身」?把馬裡奧這個方塊裡面代表衣服的褐色變成紅色,代表背帶褲的紅色變成白色。什麼是褐色?暫且說它是 0x887000 這個數字。什麼是「碰到」?馬裡奧的長方形與花朵的正方形有所重疊。什麼是「重疊」?假設馬裡奧的這個方塊佔據屏幕(什麼是屏幕?一個能裝下 256 × 240 個小色塊的矩形)中 X 方向 101 到 116、Y 方向 21 到 52 之間的區域,那麼只要這個區域內有一點或更多點也被花朵所佔據(比如花朵處在 X 116 到 131、Y 21 到 36 之間的區域內),我們就認為兩者有所重疊。

若給定以八個數值代表的兩個矩形區域,請寫出判斷兩個區域是否有重疊的 C 語言程序。如果你能寫出來,那麼祝賀你,如果有朝一日你想自己用 C 做一遍 NES 版本的《超級馬裡奧》,你至少知道讓他變身需要做什麼了。

是的,C 語言也許「只能」做數學題。可是,絕大多數遊戲的運行過程就是不停地做數學題,而所謂編寫遊戲,也就是把遊戲的規則和遊戲的效果轉化為數學題而已。其中不少題目電腦都已經知道怎麼解——是別的程式設計師事先告訴它的——比如「求一堆散落在三維直角座標系之中的多面體在 8(x−3)−10(y+1)−11(z−1)=0 這個平面上一個給定範圍內的投影」或者「給定一些彼此相連的頂點,求任意兩點之間的最短路徑」之類的數學題,它只需要千萬分之一秒就能給你解好。這種能力有什麼用?電腦上 FPS 遊戲的本質活動就是不停地求三維座標系下的多面體經過變換之後在二維平面上的投影,不停地判斷兩個多面體是否彼此重疊,以及不停地尋找兩個頂點之間的最短路徑,最終達到讓怪物衝到你面前咬你一口的目的。不止遊戲如此,其他軟體也都差不多,每一個細節都是某種數學題——比如知乎頁面頂端的藍色導航條背景,就是 CSS 描述的一個淺藍到深藍的漸變——漸變是怎麼回事呢?給出兩個數字分別代表兩種顏色,以及第三個數字代表一段距離,求一系列顏色的數值以及次序,使得這段距離中兩種相鄰顏色之間的變化最小。數學題。別說 C 語言,一切程式語言最終都只能做數學題,根據給定的數據,算出另一些數據,算出更多的數據,然後存貯、發送或者呈現算出的數據。

不過我能理解你的困惑。投入大量時間看完教程,結果只能在黑框裡輸出一串數字。這是在學編程還是在向七十年代致敬?編程是這樣無法給人成就感的活動嗎?是,也不是。看你的表述,應該不是小孩子了,因為小孩子不會因為初學編程能做的事情很少而沒有成就感,或者說,覺得這樣做沒有成就感的小孩子根本不會繼續學下去。最初學編程的成就感單純來自於「我居然可以指揮機器做一些事」,至少我小時候用中華學習機編一個程序幫我算暑假作業上的四則運算題時是這樣感覺的。寫出這些程序並用它解題雖然遠比自己動筆去把題目算出來費時,卻讓人樂此不疲。那時候我還不知道馬裡奧碰到花會變身這種事情其實也是靠編程編出來,所以我也不會去想學編程「並不能做什麼」。

無奈大多數人過了一定年紀就很難再靠「我能指揮機器」這種簡單原始的快樂來驅動自己學編程。見過世面,聽過傳言,欲望和野心變得複雜而龐大,你想要圖形界面,音樂音效,人工智慧,雲端同步,可是你悶頭學了幾堂課,還是只學會在黑框裡顯示一串數字。你懷疑這是學 C 語言的錯,於是你到知乎上來問了這個問題。

你的疑惑是有道理的。

如果能把編程學下去,日後你就會明白,任何程序都是一座冰山,最終用戶能看到的界面和使用的功能,只是程序浮在水面上的十分之一。知乎這個網站其實也是個運行在某臺電腦上的程序,你能看到的十分之一是用什麼編寫的呢?HTML,CSS,JavaScript,或者 Objective-C。而你看不到的那十分之九是用什麼編寫的呢?Python。這些你無法直接觀測到的 Python 程序運行在世界某個角落的某些計算機上,隔著光纜、雙絞線和無線基站,為你面前或掌上的用戶界面注入生命。

……可是 Python 是用什麼編寫的呢?C 語言(當然,這麼說並不嚴謹,Python 理論上可以用任何其他語言實現,實際上也已經被用很多其他語言實現了,不過這並不是重點)。任何程式語言都是實現某個功能的工具,Python 實現了知乎這個網站的大部分功能,而 C 實現了「用 Python 寫程序」這個功能。為什麼是 C?

C 很彆扭又缺陷重重,卻異常成功。固然有歷史的巧合推波助瀾,可也的確是因為它能滿足對於這樣一種系統實現語言的需要:既有相當的效率來取代彙編語言,且又足夠地抽象而流暢,能夠用於描述各種各樣的環境之下的算法與交互。
C is quirky, flawed, and an enormous success. Although accidents of history surely helped, it evidently satisfied a need for a system implementation language efficient enough to displace assembly language, yet sufficiently abstract and fluent to describe algorithms and interactions in a wide variety of environments.
——C 語言之父,Dennis M. Ritchie


C 是初代程式設計師所使用的語言,那時候硬體很貴,軟體必須高效;而計算機的用戶都是職業程式設計師,對於硬體有足夠的理解。C 貼近硬體,就意味著它容易譯成機器能懂的語言,而它的設計者也並不需要操心普通人學起來可能會比較困難——而且,說真的,其實也不很難。但是,這麼多年過去之後,軟體規模變得越來越大,C 就像錘子和手鋸,修小木屋得心應手,造摩天樓就比較力不從心;但 C 語言可以用來造出其他更適合建造摩天樓的工具,乃至組成摩天樓的預製件,就好比用錘子和手鋸造出挖掘機和吊車、混凝土板和一體門窗一樣(當然,這個類比並不十分貼切。可是沒有什麼類比能貼切地描述軟體工程,因為軟體工程像許多東西,卻又什麼東西都不像)。

所以,回到你的問題上來,是的,學會 C 計算機語言真的可以開發出很多東西,但除非內力深厚,場合適當,並且閒得蛋疼,大多數人不會拿 C 或者只拿 C 來開發太大的東西。如果你只是想要一門能夠讓你「編輯出一個啥子遊戲或者軟體出來」的語言,而且你用 Windows,那建議你轉去學學 C#。它長得和 C 挺像,但卻能迅速地寫出至少是帶有圖形界面的程序,用起來也很方便,滑鼠點一點就能讓你對自己的程序看起來什麼樣有個比較直觀的印象。還有,在國內,C# 的教材也相當容易找到。當然 Python 也是一個很好的選擇。

<img src="https://pic4.zhimg.com/601cf5b6adc3d883a8cc9e6327f41637_b.jpg" data-rawwidth="640" data-rawheight="429" class="origin_image zh-lightbox-thumb" width="640" data-original="https://pic4.zhimg.com/601cf5b6adc3d883a8cc9e6327f41637_r.jpg">
另外,還有一件事你必須弄明白:現代的所謂編程這一活動,其實大部分時候是在「合理地堆砌別人已經實現的功能來實現新的功能」,C 語言莫不如是,比如 printf 這個東西,是別人做出來的「把一些數據按照指定格式輸出到屏幕上」這一功能。而別人還做出來許多其他功能,比如「在發現用戶短時間內連續兩次按下滑鼠又鬆開的時候調用你寫好的一個函數」。學會怎樣在 C 或者其他任何程序語言中使用這些既有功能,也是學習編程的一門重頭戲。等你弄明白這一點,你也就找到了你問題的答案。

尾注1:題圖畫錯了。馬裡奧身寬應為 16 像素,我畫成了 17。
尾注2:NES 上的超級瑪利奧使用 6502 彙編完成,並不是 C,碰撞檢測也不是像素級的。
尾注3:我不是易語言發明者。

相關焦點

  • 學會了C語言真的能開發很多東西嗎?
    (掃描二維碼也可以下載)https://www.jianguoyun.com/p/Df3pSXcQ_YCzBhjr9UI比如說馬裡奧碰到花朵就會變身,這麼一個簡單的例子,很多東西也都可以套用這個例子。C 語言(當然,這麼說並不嚴謹,Python 理論上可以用任何其他語言實現,實際上也已經被用很多其他語言實現了,不過這並不是重點)。任何程式語言都是實現某個功能的工具,Python 實現了**這個網站的大部分功能,而 C 實現了「用 Python 寫程序」這個功能。為什麼是 C?
  • 讓孩子從小接觸英語原音動畫片,那麼真的可以學會一門語言嗎?
    讓孩子從小就接觸英語原音動畫片,那麼真的可以學會一門語言嗎?我們都是十分得羨慕那些可以從小的時候就可以從父母那裡可以學的到兩種語言的人,因為我們普通人大多都是沒有這種特殊情況下的家庭環境,所以我們能夠學到的只是一種語言,自己的母語。
  • 三天學會C語言編程 | 中篇
    本文是《三天學會C語言編程》的第二篇文章,承接上一篇《三天學會C語言編程 | 上篇》。本文重點介紹C語言的數據類型、表達式、變量和函數等內容。如下表是C語言支持的數據類型(部分),這裡先不用過多理解,只需要知道有這些類型就行,後面會詳細介紹。通過這個表可以看出不同類型的數據佔用的內存空間大小是不同的。
  • C語言,C++,C ,Java之間的關係
    現在,隨著計算機的性能越來越強大,其內部的機構也會變的越來越複雜,很多新的東西也正在漸漸的出現並且發展起來比如大數據,vr,等。現在,小編先來給大家說下計算機語言的發張,一臺計算機最本質的語言是機器語言,由01010101的代碼組成,CPU處理的也是由由010101的代碼組成的數據。但是,這種語言太簡單了,不好理解。
  • C語言中「c=a+b」,這種結構合理嗎?
    C語言會同意一些"令人震驚"的結構,下面的結構是合法的嗎,我們來看看幾個例子。 c = a+++b; 以下代碼是合法的嗎,咋的一看不禁有這樣的疑問?
  • 為什麼很多人選擇放棄學習C語言?
    C語言找工作的門檻提升了早期的程式設計師自學一下C語言基本上就能進入公司了,然後在工作中慢慢提升,隨著這些年軟體行業的飛速的發展,相對來說行業準入的門檻提升了,再加上培訓公司的切入導致很多人覺得不參加個培訓就不能找到工作似得。其實決定性的因素還是入行的門檻提升了,不像當年有點C語言的知識就可以找工作了。
  • 【C語言】02.第一個C語言程序
    平時我們在Windows中寫文章,可以用記事本、Word等文本編輯工具。在Mac中呢,我們可以安裝一些文本編輯工具來寫代碼,比如UltraEdit(點擊連結可以下載UltraEdit)。當然,在實際開發中,為了提高開發效率,一般會使用開發工具,開發工具的好處,我在前面文章中已經說過了。不過呢,開發工具屏蔽了很多操作細節和語法細節,不利於初學者直觀、系統地學習一門語言。
  • 法國人的自白:聯合國六大語言好學嗎?
    先來看看法國人是怎麼吐槽這些語言的吧!雙十二學習趴回復關鍵詞「雙十二」可查看全額獎學金班、超給力預定金詳情哦!在聯合國的所有會議、官方文件,以及有關記錄、事務中可以使用的語言稱為聯合國工作語言,聯合國的工作語言共有6種:漢語、英語、法語、俄語、阿拉伯語與西班牙語。
  • C語言簡單編程速成
    最明顯的是 C++ 語言,這是一種以相當露骨的方式命名的語言,它構建在 C 語言之上,創建了一種很好的面向對象語言。不過,許多其它語言的存在是有充分理由的。計算機擅長一致的重複,因此任何可預見的東西都可以構建在程式語言中,對程式設計師來說這意味著更少的工作量。
  • 為什麼指針被譽為 C 語言靈魂?
    編譯器也可以通過類型檢查來排除一些編譯錯誤。這就是指針存在的必要性。實際上任何語言都有這個需求,只不過很多語言為了安全性,給指針戴上了一層枷鎖,將指針包裝成了引用。四、多級指針說起多級指針這個東西,我以前大一,最多理解到 2 級,再多真的會把我繞暈,經常也會寫錯代碼。
  • 為什麼很多人學不會C語言?學霸說:你要是像我一樣學肯定能行
    為什麼很多人學不會C語言?C語言作為一門入門級語言,是大多數編程者的學習首選,它不是應該是一門容易上手的程式語言嗎?而且大學都會有老師教的,為什麼很多人學不好C語言呢?其實筆者認為學不好C語言的主要原因都是出在學習者自己的身上!
  • 真的可以用C語言實現面向對象編程OOP
    C語言的特性,實現OOP C是一門面向過程的語言,但它依舊可以實現大多數面向對象所能完成的工作。比如面向對象的三大特性:封裝、繼承、多態。我們以下圖來寫代碼舉例子。 OOP真的那麼重要? 從大學到工作至今,在嵌入式領域中一直是使用C語言,而我在學習C++的過程中,看的代碼越多,代碼量越大,越來越覺得C++對於大型軟體架構的良好可控性,和對以後程式設計師維護代碼時良好的可讀性; 個人認為:C語言中最大的成功在於它的指針,但是也是最容易出錯的,想要理解C,必須要掌握指針。雖然說,語言只是一門工具,但是這是基礎.
  • 真的可以,用C語言實現面向對象編程OOP
    C語言的特性,實現OOPC是一門面向過程的語言,但它依舊可以實現大多數面向對象所能完成的工作。比如面向對象的三大特性:封裝、繼承、多態。我們以下圖來寫代碼舉例子。OOP真的那麼重要?是C;C實現的nginx的並發量是C++實現的apache的幾十倍,關鍵是要理解語言背後的思想。當然這不是為了OOP而OOP,實在是OOP的一些特徵,例如封裝,多態其實是軟體工程思想,這些思想不分語言,遵循了這些思想可以使得程序更有彈性,更易修改和維護,避免僵化,脆弱的性質。
  • C語言簡明教程(一)C語言簡單剖析
    C 語言相當靈活,用於執行幾乎所有計算機可以完成的任務,既可以用於編寫應用程式,還可用於編寫作業系統,偉大的 Windows 和 Linux 作業系統的內核就是使用 C 語言開發的。C 語言包含了基本的編程元素,後來的很多語言(C++、Java 等)都參考了 C 語言,說 C 語言是現代程式語言的開山鼻祖毫不誇張,它改變了編程世界。
  • 你真的知道C語言裡extern "C" 的作用嗎?
    經常在C語言的頭文件中看到下面的代碼:
  • 聯合國六大語言好學嗎?法國人的心裡話
    聯合國的工作語言共有6種:漢語、英語、法語、俄語、阿拉伯語與西班牙語。你對這6種語言都了解嗎?你知道法國人對這6種語言是怎麼看的嗎?我可以向你保證,它絕對不像任何一種已知的語言。-On dit souvent qu』il faut 10 ans pour apprendre le chinois.要10年才能學會中文。
  • C語言我很皮|不許有人比我皮
    C語言可以這樣比喻,是一門非常強大的內功心法,學會它可以做到一法通萬法。這也是它至今不衰的原因。
  • 學習C語言的辛酸淚(四)
    不得不覺得自己笨了,因為我害怕我花了好多時間這麼做然後發現錯了,而且我真的做得到去花好多時間在之前的練習上而不是當下的、即將要上交的作業,或是刷刷oj那種嗎?誒,害怕,「船到橋頭自然'沉'」。    第三,關於老師。
  • C語言?c+?到底先學哪個才能更好的理解編程,這些你造嗎
    最近大一新生們剛剛結束第一個學期的學習,接踵而來的問題也越來越多,不同的學校有不同的學習節奏,但是基本上都是從C語言或者c++開始學起。現在越來越多的人對於「學習C語言還有必要嗎?」這件事比較糾結。
  • 書籍分享|零基礎學習C語言(附電子書)
    它能為你系統學習c提供一個良好的平臺。作者:普拉達《The C programming language》拿到這本薄薄的書,很多人開始懷疑,C語言是這麼幾百頁能講清楚的麼。看完這本書,我想答案已經很明了,卻真的讓人感到震憾。什麼是好書?無法刪減的書才是真正的好書。