[C 語言] 程式設計教學:學程式設計一定要學 C 語言嗎?

【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    在這篇文章中,我們不急著寫程式,來談談一些和學習 C 語言相關的議題。

    學程式設計一定要學 C 語言嗎?

    如果各位讀者是因一些非語言本身的因素要學 C 語言,像是學校指定用 C 語言來寫程式或是因個人興趣學習 C 語言等,那麼,想學就學,同樣的情境也可以套用在其他的程式語言上。不過,如果是因為單純要學一個程式語言,好像大專院校都用 C (或 C++) 做為學習的工具,那倒不急著跳進來,其實還有很多選擇。

    大專院校使用 C 語言,有其考量和歷史因素。除了組合語言,C 語言大概是最貼近電腦的高階語言,C++ 則保留 C 的特質但加入許多更高階的語法特性。對資訊科系的學生來說,除了會資料結構、演算法等抽象的思考方式之外,也要學一些電腦本身的知識,像是作業系統、計算機組織等。像 C (或 C++) 這種同時有高階和低階特性的語言就會是合適的工具。

    對於不是資訊出身又沒學過程式設計的讀者來說,C 語言不一定是最佳的第一個語言,因為從開始學習到寫出東西的養成期較長,對於初心者來說易有挫折感。雖然筆者不是要吹捧 Python 最好最強,但 Python 等語言確實提供了較平滑的學習曲線,比較快就可以把程式用在實際的用途上,比較容易培養成就感。

    程式語言基本上就是在效能和易用間做權衡,不同的情境會使用不同的工具,沒有一個語言可適用所有的情境。C (或 C++) 的重要性是無庸置疑的,但不一定每個人都要變成 C (或 C++) 達人。我們這系列文章是以學習 C 為出發點,之後的內容會以 C 為主。

    C 語言是資訊界的骨幹

    比起其他的高階語言,C 語言 (或 C++) 多用於電腦界的基礎建設項目,像是

    • 作業系統
    • 驅動程式
    • 資料庫
    • 伺服器
    • 其他高階語言的編譯器或直譯器
    • 其他高階語言的延伸模組

    我們不一定會直接使用 C 語言,但很多軟體或函式庫背後都是使用 C 語言實作的。

    現在的程式語言大抵上是朝著簡單易用的方向前進,僅在核心功能仍然需要 C (或 C++) 來撰寫,甚至也有一些替代的方案來簡化這個部分。像是 Cython 就是用來取代人工撰寫的 C 程式碼,幫 Python 程式加速;同樣的例子還有用來撰寫 PHP 模組的 Zephir。許多語言都發展出 FFI (foreign function interface) 模組,用來取代原生的 C API,其實也可以用 Rust 寫元件,會比直接用 C 來得簡單一些。

    有些程式運行環境沒有那麼多運算資源,像是一些嵌入式裝置 (embedded devices) 或物聯網 (the Internet of Things) 裝置等,這時候,我們沒有太多選擇,甚至 C++ 編譯環境都顯得過度奢華,大概還是要直接使用 C 語言來撰寫程式。在少數比較高檔的嵌入式裝置,可以放一些相對肥大的運行環境,像是 Java 或 C# 等,但這並不是嵌入式系統的常態。

    C 語言的核心概念短小精悍

    其實 C 語言並不難,甚至可以說 C 語言相當簡單,因為 C 語言的核心語法不多,很快就可以學完。C 語言定義了一小組核心語法,其他的功能都使用函式庫來完成,這使得 C 語言編譯器易於實作;每當我們開發出一個新的硬體,第一個想到的都是先開發一個給該硬體使用的 C 編譯器,之後就可以慢慢地移植其他的函式庫到這個平台上。

    由於 C 語言的概念相當精實,學完 C 語言後,同樣的概念可以繼續延伸到 C++、Java、C# 等語言;雖然這不代表我們馬上就可以學會其他語言,但概念通了以後,我們只要學習語法的部分即可,程式設計的概念在學習 C 語言時就不知不覺打下基礎了。

    不可否認地,學習 C 的確對學習 C++ 和 Objective-C 等語言有直接助益的,因為這些語言是在相容於 C 的前提下所建立的新語言。但我們應該直接使用 C++ 和 Objective-C 的最佳實務,而非繼續使用相容於 C 但次佳的手法;例如,雖然我們可以在 C++ 和 Objective-C 中撰寫 C 風格的物件,但我們應優先使用這些語言提供的物件系統,而非繼續使用 C 風格的擬物件語法。

    學 C++ 或 Java 前要先學 C 語言嗎?

    由於歷史緣由,很多語言和 C 的確長得有點像,像是 C++、Java、C# 等語言的確有參考 C 的一些特質;甚至 JavaScript 這種本質上向 Scheme 致敬,但為了商業考量,刻意在語法上向 C 及 Java 靠攏。那麼,我們是不是要先學 C,再來學 C++ 或其他語言呢?其實這是沒有必要的,這些語言只是在語法上參考前人,但不會完全照抄其特性,需要學什麼語言,大可以直接學習該語言即可。

    由於 C++ 的確保留一些 C 的特性,的確會有一些人會覺得要先學 C 再學 C++,像 C 程式設計藝術 (C: How to Program) 的前半部是 C 語言,卻在後半部偷塞 C++,就給讀者這樣的暗示。如果讀者真的需要學 C++,先學 C 是沒有必要的。很多情境,在 C 和 C++ 的處理方式不同,實在不需要學兩次。像 C++ 有 vector,我們大可不必再回頭用 array;除非是為了相容於 C 程式碼,我們也很少在 C++ 中使用 C 風格字串。連 C++ 的爸爸 Bjarne Stroustrup 都特定發了篇文章說 “Learning Standard C++ as a New Language.” (可見這裡),我們大可不必在繞遠路。尤其 C++ 在 C++11 標準後出現許多新的語法,和 C 的差距越來越遠了,除了相容性,我們甚少要再寫 C 風格的程式碼。

    Java 和 C 就離得更遠了,除了表面上一些語法相近以外,更重要的是背後運行的 Java 平台。C (或 C++) 由於貼近硬體,除了語法和標準函式庫是相同的,很多系統 API 是相異的,如果去觀察一些跨平台 C (或 C++) 的函式庫,其實內部都用很多條件編譯來處理各個平台的差異性,而 Java 基本上就直接把機器抽象化,程式設計者就不需要再煩惱這些問題了。C++ 的爸爸 Bjarne Stroustrup 對 Java 的評論是 “Java isn’t platform independent; it is a platform.“,值得我們思考。同樣的情形也適用於 C#。

    程式設計有一部分是抽象思維,有一部分是實際工具,先學 A 再學 B 通常對抽象思考有幫助,但語法和工具都要重新學習。C (或 C++) 可用的開發工具會受到系統的影響,而不像 Java 或其他高階語言那麼地跨平台,我們也會在後續文章中介紹這一部分。

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【追蹤新文章】
    Facebook Twitter Plurk
    標籤: C 語言