今天周末,換個話題。最近有一篇文章引起我的「注意」,是讀了「眼神死」的那種注意。讀完之後,心生一語——鞭數十,驅之別院。
文章作者是一名學生,該文「看起來」是第一線觀察學校電腦程式設計的教學現況有感而發。懂得觀察很重要,但過於武斷這一點,要不得。
藉由這篇文章,山姆也要來好好地,大放厥詞一翻。(看了會動肝火,屬正常反應,請勿驚慌)
首先,關於「叫朋友學 C/C++ 是缺德行為」的笑話,真的笑一笑就好,不要當真。那些認為好笑的,十個有九個是 C/C++ 語言的「逃兵」——抓不住要領,學不到精髓,只好跟著別人笑。
再來就是「比一比,看誰最會印 Hello World!大賽」,「印出 Hello World」不知是誰開始的,但我認為她(他)的初衷不是拿來「測試(Benchmark)」誰能最快印出 Hello World,而是以簡單且有趣的範例,來教程式語言。
每次看到有人拿這比賽來說嘴,說 C/C++ 很難學,很不友善。我想反問:證明了「Python/Ruby/JavaScript 是一個很會印 Hello World 的程式語言」,有什麼意義?
小明用 Python 竟然比小憲用 C++ 早一分鐘印出 Hello World!
可以再搞笑一點。?
「該不該有更多人學習 C/C++ 並當做作專業技能?」
這個問題的答案,只有一個:當然要。
這幾年,許多有潛力的的「系統程式語言」輩出,Go, Rust 都被認為有機會「幹掉 C++」。許多人這麼想,但我認為還早,甚至永遠不會發生。
我認為應該要培養更多 C/C++ 人材的理由是,許多資訊基礎建設如瀏覽器、資料庫、作業系統,甚至那些瞧不起 C/C++ 的程式語言,也是以 C/C++ 寫就。
以 C/C++ 開發的軟體專案會用其他語言改寫嗎?有些會(會做這種決策的人要嘛太蠢,要嘛錢太多),但多數不會。新的專案會選擇 C/C++ 做為主要開發語言嗎?肯定會,雖然我沒有數據證明,但我相信數量比你想像得要多。
我覺得 C/C++ 之所以被認為難學,是有一群人讓她變成這樣。什麼人?「門外漢」。
一個人一輩子,不是只能夠學一種程式語言。我常掛嘴邊的話:「我最討厭 Java, JavaScript, Assembly」,討厭歸討厭,我不會(真心地)告訴別人不要學那些我討厭或覺得困難的語言。專業工作者必須備有主槌、副槌、小槌子,不同的問題,要用適合該問題的工具解決。
我同意 C/C++ 相較於其他程式語言,其進入門檻相對較高(這個門檻不是指「印出 Hello World 難易度」)。但是,不要讓學生初接觸程式設計就挑戰難度較高的語言,什麼時候才適合?最直覺(無腦)得答案是:有需要的時候。
可是瑞凡,C/C++ 不是那種要用的時候「撿」起來就可以直接上手的工具,再怎麼有天份、資質的人,也要投入一定的時間,才能建立起正確而且紥實的 C/C++ 語言基礎。需要的時候再學,通常來不及啊。
學習 C/C++ 不僅僅只學該程式語言,電腦運作原理、軟體程式的抽象性、如何拆解問題,都是學習的一環。克服困難的問題所獲得的成就感,除了讓人大幅成長,而且還想一鑽再鑽,更上層樓。真正進得了「專業軟體開發者」大門的人,是那些需要「細心呵護」的嫩芽嗎?
以學習的角度來看,程式語言概分兩種:
高階語言——離電腦運作原理很遠的那些,把開發者當「寶貝」,難的東西「藏」起來,說好聽怕你弄髒手,其實是「陰暗」的角落不讓你碰,因為你太「弱」了。那些不讓你碰的地方,設計者做了許多取捨,有些東西導致你在學習其他語言時,摸不著頭腦,搞不清楚狀況。
引用本文開頭所指的那篇文章中的一段:
C/C++ 是靜態語言,意思是它的變數需要定義型別且不能改變,這對新手是一個困難;C/C++ 是編譯式語言,程式必須先經過編譯才能執行,編譯過程對新手也是一個困難。
是「相對困難」,但這難度,很難克服嗎?我不這麼認為。「型別系統(Type System)」是 C++ 程式語言必備基礎,但就像教「數學原理」,「1+1 為什麼等於 2」?有那種教一下就會的小朋友,也有一些要花點時間才能接受的孩子,投入時間後,多數孩子都能學會基礎數學。
理解 C++ 的「型別系統(Type System)」不只在該語言有用處,同樣的觀念適用於不同的程式語言,雖然不是一對一對應,但原理互通,多有關連。這也是為什麼「學成 C/C++ 之後,要上手其他語言變得簡單」的原因之一。
真正讓人吐血的是這段:
再來是最大的問題,C/C++ 語法複雜,且在 AI、網站後端、App 等領域較不適合,現在通常是用其他的語言來設計,C/C++ 只會用來實做底層的功能。
希望讀者原諒該位作者,他真的不知道自己在「工蝦小」。這種不堪一擊的論述,以後再找時間談。
如果「新手不適合學 C/C++」,那要什麼時候學?關於學習 C/C++ 或其他程式語言,該聽誰的?「戰士」,還是「逃兵」。
在我眼裡,C++ 是一種許多面向都在「越變越好」的程式語言,覺得學 C++ 沒前途、沒市場,那是因為等級還太低,經驗、火侯還不夠。要怎麼做才能拉高等級?如何成為一位真正的「C++ Pro」?我認為:
① 反覆閱讀幾本好書
② 做中學的實驗精神
③ 待領域相同的職場
④ 跟隨一位對的導師
⑤ 公開分享學習心得
⑥ 三年
對,「三年」。多數人至少需要投入三年的時間,把 C++ 當做專業技能來學習,才有機會成為有實力的「C++ Pro」。
對我來講,其實C++就是缺一個好用的package manager,當然brew/apt/dnf都是C/C++的package manager啦,但是他們和binary混在一起,真的挺混亂的。
其他的所謂C++ package manager就啥都沒有......
我在工作中用到 vcpkg,有些問題,但整體來說,還蠻不錯的。而且,已經跨平台到 macOS 以及 Linux。還沒試過的話,可以一試。
thanks
另外,我覺得教初中生學C++實在太苛求了,中學生學會編程Concept,甚至寫一寫web app,小遊戲什麼的已經很了不得了.......
概念是最重要的
然後,你引用的文章裡面第一個例子和第二個例子剛好調轉了C++和C.......
另外,你的文章今天應該是 19天
延平中學好像有教 C++。我不是第一線教育者,沒辦法做出「現在的中生學 C++ 太苛求」的結論。
作者有注意到,但因為是在 Matters 發文,好像無法更改?
因為我的文章是從 Day 0 開始,所以會差一天。C++ 嘛,計數從「一」開始,容易有臭蟲 XD
不是這個意思,你發了20天,所以今天應該是19天,你現在有兩個18天
原來如此,是我眼殘,感謝。 :)
一點淺見分享,我自己覺得在台灣有個很現實的問題,學習C++在目前的就業市場上是一種投資報酬率不高的投資。
打開C++的職缺,先扣除那些打著是C++的名號其實骨子裡面是C語言的職缺不談,大部分的職缺所需要的C++人才都是需要對C++有一定程度了解,也就是不需要junior C++ engineer,所以當學生畢業踏入社會時,很難花這麼久的時間去學習C++,所以會選擇上手門檻比較低的程式語言學習我覺得本質上也是現實考量。
關於這句話「新手不適合學 C/C++」,需要先給定義何謂「新手」。
這個「新手」可以指幾類人:
我個人目前在澳洲的資訊行業工作,本業是寫 C++。我在這裡體會到一個跟台灣截然不同的環境。澳洲的資訊業是新興產業,主要以 Internet 創業為主,沒有太多人在搞基礎建設。這裡沒什麼人在學 C++,C++ 職缺也極為稀少,整體行業主要是 Web 前後端跟移動開發為主。
C++ 還是很重要,而且大概永遠不會消失。只是現在確實是一個新的時代,就算是「專業軟體開發者」也不一定有需要寫 C++ 了。
C++ 在後端/網頁/App開發這三個領域真的幾乎沒用。
確實,C++ 在該些領域是弱勢,這個「弱」,倒不是程式語言弱,是動機太弱。
Web 領域 C++ 確實插不上手,但是,Web 領域以外還有很大的機會。而且,網頁後端、App開發,再幾年,C++ 就不會像現在一樣,只有挨打的份了。
是阿,被你發現惹XD
就新手而言可能推薦學python比較適合,因為軟體開發所需的核心知識主要不是語言本身(語言只是工具),而python語法好上手又有許多套件可以用,自然會讓人把開發的注意力從語言本身挪到軟體建構所需的元件。
例如製作一個網頁需要甚麼? 如果安裝django並用MVT架構,前端應該有個router將view串到對應的處理函數,後端在根據函數需求連model資料庫、業務邏輯等將回傳數據套入template。
安裝上只需管理虛擬環境,現在anaconda已經大幅度簡化了,創好環境pip install django即可。
製作以上的架構時,router、model、template等都是一些簡單的類別(model)、函數(router)和檔案(html和模板引擎)。python是漂亮的讓初學者(弱者)在不必碰觸到大量元件背後的原理的情況下,可以就基礎元件有初步的了解;若真的有興趣的人,會再進一步研究,像階層式router是怎麼實現的?網頁是如何渲染的、資料庫是怎麼實現的(如何parse SQL語法,如何連接資料庫等)。
另一方面,C++套件剛開始就要處理連結、編譯,我是寧可看makefile或用cmake的人,當然也可以用其他套件管理工具,例如conan等;但無論如何仍然要對連結、編譯有一定的知識,知道他會自動幫你生makefile等讓你可以一鍵安裝,用GUI也可以,但vs-studio太重qq。然而,不可否認的,這些東西對毫無編譯程式經驗的初學者是很大的學習成本,而且這些知識和我們上面提到的元件沒有任何關係,純粹是編譯語言需學習的技術。
我是覺得能力到了,自然會關注重要的議題,看到了c++在底層控制、連結編譯處理的靈活,想了解跨平台是怎麼一回事,或看到在建構大型資訊基礎設施的嚴謹性(基於型別、編譯器支援私有成員的存取性,類別繼承的架構等),自然會具有 "明確學習目標" 的 "再學者" 來尋求這門語言(小弟也是其中之一,來看這系列的專欄的),而不必讓連構成軟體服務的元件都不甚了解的人,先有這類的學習成本(當然以上的學習成本還尚未列入語言本身,像有提到型別等議題)。
TLDR;
型別的學習成本:
如果只是在變數前面加一個型別名稱作為聲明,這樣的語法確實沒有甚麼學習成本,但型別本身有很多連初學時都不可避免的議題,例如型別轉換、基於類別的型別轉換、複合型別(指針、參考)。
這些內容其實對初學者而言也是相當大的學習成本,若能學起還當然非常有幫助,因為其他語言或多或少都會遇到這些問題(不過不像在c++被直接攤開來談),但我想仍是上述所提到,對於構成軟體的元件是最他們現階段較重要的學習目標。