如果你看完這些書單, 有寫出什麼有趣的程式嗎? 若是沒有, 不是你不用功, 而是這些書單耗掉你太多時間了。
你也會懷疑有輕鬆的方式學習 c++ 嗎?
絕對有!
以下是 c++ 受害者才能寫得出來的文章
要是先看到劉未鵬的文章, 我就不會寫這篇了, 我和他有類似的想法, 但我的文筆和他差太多了, 無法把我想表達的觀點寫的很清楚, 不過寫了就寫了。
我和劉未鵬文章的共同想法: 不想在 c++ 語言細節/特性的地方打轉, 一直注意語言細節/特性, 很容易鑽進去這個地方, 不容易逃出來, 我前陣子就鑽進 template, 好不容易才逃出。或是 overloaded function 怎麼決定採用哪個 function, c++ primer 寫的很清楚, 那些規則很煩人, 但你需要去看這些嗎? 不, 一開始不會有這需要, 一開始的你絕對不會寫成這麼複雜, 讓自己踩到陷阱, 頂多是 print(int), print(char) 這種簡單的用法。
我想用 c++ 寫點有趣的東西, 例如 os kernel, 還沒完成, 目前只建好目錄 (這可容易多了), simple_os 是用 c 實作, 不能用 c++ 實作一直是我的遺憾; 用 c++ 寫的實作品有作業系統之前的 scheme, 和作業系統之前的 c++ library, simple_gui。我覺得這些都比去學習 c++ 語言細節有趣多了。而且用到的 c++ 特性/語言細節很少, 這也是我受害之後才有的想法。
我也不想再看什麼條款的書, 好像一個不注意, 又要落到 c++ 陷阱中了。不是書籍內容不好, 相反的, table 1. 介紹的書本本都是大作, 但我想把注意力集中在用 c++ 寫出我想寫的程式。
從 C 到 C++ 物件導向革命 - 抄襲的作品 |
「從 C 到 C++ 物件導向革命」這本書雖然不錯, 我也有, 但這是抄襲的作品, 請看作者自己的發文。《Chris Chen (陳建維) 對於「從 C 到 C++ 物件導向革命」的說明》
我不是來贊同書單的, 相反的, 我是來減少書單的, 畢竟看的書要是多了, 誰也不相信能學的輕鬆。
我把 c++ 分為兩種使用者:
- c++ 使用者
- c++ 底層開發人員
而到了 2016 年, 至少又要加上幾本書了。第四版的 the c++ programming language, 第五版的 c++ primer, 這兩本這麼厚, 吃的下的人不多, 到不是因為看不完, 而是會排擠學習其他知識的時間。真要挑一本看, 當然是看 Bjarne 的書, 因為我實在想不出不看 c++ 發明者寫的書而非要去看其他人寫的理由。
Effective C++, More Effective C++, 看著手邊的 effective modern c++, 未來再看到 more effective modern c++ 我應該也不會意外。拿到書後沒有急著看 effective modern c++, 我的心境已經和之前不同了, 當初 Effective C++, More Effective C++ 看的津津樂道, 不過對於 c++ 的掌握沒什麼幫助, 不是書不好, 而是我忘光了書中內容了, 而這 3 本薄薄的, 不會花上太多時間。
你不想在語言上花太多時間吧! 只有 c++ 本身並不能寫出什麼有趣的程式, 我好像打自己臉了, fig 1 就是用 cout 畫出整個畫面, 但其實也沒那麼簡單, 如果只有 c++ 本身的知識, 也是做不到的。fig 1 是一個很有趣的程式。
難道你很喜歡演算法那些題目嗎? 什麼反轉二元樹, linked list, graph 演算法, 二元搜尋樹, 河內塔 ... 那你是個例外。通常把某個平台的 api 組合起來的程式才是我們更常見的程式。
像這個看起來很簡單的《文字大富翁》只有 c++ 本身的知識, 是完全寫不出來的, 光是畫面的繪製就難倒你, 寫出這樣的程式有沒更吸引你呢?
使用 c++ 本身甚至連抓取特殊按鍵 (F1, Pause 之類的) 都有問題, 我們更常會需要類似的功能, 所以還得知道怎麼辦到這件事情, 想寫視窗程式吧, 還得學習 qt, 想寫手機 app, 還是可以學 qt, 想寫網路程式還得學 socket, 想在 linux 上寫程式, 得花時間看 apue, 想寫 windows 系統程式, 還得看大奧祕之類的書, 想寫 compiler/interpreter, 得找編譯器的書來看, 想寫 os, 得找 os 相關的資料, 想寫網頁程式, 那你挑錯語言了, c++ 會讓你很累。除了語言本身還有想寫的領域知識得學習, 把時間花在語言本身不是太划算。
劉未鵬寫文章的時候應該還沒有這本 -《C++程式設計原理與實務-第二版》, 這是 Bjarne 寫給初學者看的, 強力推薦。
fig 1. 使用 cout 來繪出畫面 |
再來本《c++ 標準庫》, 我知道有免費的英文網站可以查, 但中文是這本書的最大價值, 你懂的, 如果你要靠免費的英文網站學英文又學 c++, 那你挑錯教材了, 很有可能落得兩頭空, 既沒有學好 c++ 標準程式庫, 英文也沒有進步, 一心二用是很困難的, 連 Don Knuth 一次都只做一件事情, 我們平凡人就更無法同時做兩件事情了。
接著該讀哪本呢? the c++ programming language the 4th 中文本, 現在的我會選這 3 本書來學習 c++, c++ primer 就不讀了, the c++ programming language 應該可以覆蓋 c++ primer 內容, 我會讀 c++ primer, 完全是因為侯捷的翻譯, 如果不是侯捷翻的, 我只會去看 the c++ programming language, 看聖經版就夠了。但這本不是馬上看, 而是用 c++ 寫了不少程式後, 再來翻閱, 所以實際上只要讀 2 本, 甚至也不一定要讀 c++ 標準庫, 那更是只要讀一本, 到了這時候應該不會滿足《C++ 程式設計原理與實務》裡頭的東西, 會想要再知道多一點, 就靠它了。
- C++程式設計原理與實務-第二版
- c++ 標準庫
- the c++ programming language the 4th 中文本
我認為這樣就足夠當個 c++ 使用者, 其他的就隨緣了。如果還要讀書呢? 那就再把 1, 3 拿出來讀, 正常的人應該把讀過的內容都忘光了。再來的話你應該有能力選要看的 c++ 書籍, 可以從各地的推薦書單找到自己要的。
若你要像我一樣把 c++ 用在作業系統之前的程式上, 那所需要的知識大部份就和 c++ 無關了, 可以從我的 blog 文章得知個大概。這是《系統底層開發人員》的領域, 不是《c++ 底層開發人員》, 也許有人會同時有這兩種屬性 (ex: Bjarne Stroustrup), 不過這兩樣是不同的, 我用 c 或其他語言也可以辦到這件事情, 和 c++ 無關, 用 c++ 做這件事情只是因為我喜歡 c++。
那你說沒學到的其他 c++ 特性怎麼辦, 沒怎麼辦, 不會那些不會嚴重影響到寫不出程式來。c 沒有 lambda, closure, 沒有物件導向, 沒有 template, 沒有很多語言有的豐富特性, 但我需要為你證明 c 的能耐嗎? 但若有些特性不重要, 那麼 linux 裡頭為什麼又用上那麼多的 gnu extension 呢?
語言特性真的令人又愛又恨, 怎麼選擇是智慧的表現。
c++ 最令人注目的 OO, 就是 class 的運用, 以 c++ 使用者來說, 只要使用別人寫好的 class 就足以, 這個層級的學習就簡單很多, 大多是一些 class 語法, 你不需要學習如何寫好一個 class 的 ctor/dtor/assign operator, 只要有概念即可, 大概也不會有機會去寫這些。但是 c++ 底層開發人員就不同了, 他們得知道如何撰寫這些, 除了功能正常, 還得有效率。這部份的學習就辛苦一點, 然後在加上繼承/多型又會再辛苦一點; 再來個 template class, 又再辛苦一些。
呼, 還好我是個 c++ 使用者, lucky。我們需要的大多是 RAII, 這個就比寫完整組的「那三個」容易多了, 頂多寫個 ctor/dtor 複雜度不高, 別小看這個, 光是這樣, 就已經比 c init/destory 好用不少了。overloaded 也是好學的有用特性, 看過就記住了, 但是 ... 搞得太複雜還是會害到自己。
再來就是 c++11, c++11 之後又多了很多折磨人的特性, 有 move semantic, lambda, !@#$%^&*() ... 夠折磨你的, 完了嗎? 還沒, template 的 meta-programming 加上 variadic template 技巧更是令人不知所措, 用別人寫好的很快樂, 自己寫就不好玩了。
但學習 c++11 raw string, 和 range base for loop 語法, 一點也不難, 撿起他們來吧! 如果不想學也沒關係, 使用原本的 for loop 語法也不會讓自己看來像笨蛋, 同樣的, 用 range base for loop 也不會讓自己看來很高竿。move semantic 就不用勉強自己了, 我覺得這個特性不是很容易理解, 我花了不少時間才弄懂, 就當個單純 c++ 使用者。
沒有這些之前, 你 c++ 程式也寫的好好的, 這不會造成程式寫不出來的後遺症, 不是一定要學習的關鍵。用 c++ 98 也不糟糕, 很多人也只用 c++ compiler 而不寫 c++ style 程式。我不是說不學 c++11, c++14, c++17, 而是沒那麼急迫的需要學習他, 當然你若是把自己定義為 c++ 底層開發人員, 那就一定要會的。
最折磨人的 meta-programming 呢? 這個恐怖的 template 技巧, 不會會怎麼樣嗎? 我不知道, 但我發現他並不會阻礙我完成一個程式, 我連語法都看不懂。
你會不會這樣? 花了很多時間學習的 c++ 特性, 一定要想方設法把他派上用場, 好像不這麼做就浪費了好不容易學成的絕招, 這是為用而用, 而不是真的非用不可。我很常看到 c++ template 技巧, 我一個也不會, 但我也放棄
沒用上 c++ 特異功能, 並不會使你看起來像笨蛋, 掌握 if/else, while, function call, 就已經是很大的武器了。
這樣扣完之後, 大概只要學習和 c 一樣的部份, 加上一點點 class 用法, 再加上標準程式庫, 這樣的負擔相信每個人都負擔的起, 就不會大喊學 c++ 吃不消, 當然由於那可怕的指標以及沒有 gc 加持, 應該還是比學 java 難上一點。哦! 我忘了提到 exception handle, 那個就自己斟酌吧! return error code 也還可以用, 不一定非用 exception handle 不可。
哦! 有些朋友會說我根本是在寫 c, 我不反對 (不過我堅持我用的是 c++), 但我日子很好過, 沒被這些嚇死人的特性搞死。我很常綜合使用 OO 和單純的 class 語法, 哪個寫來順手就用哪個, 以前我也很煩惱要用 OO 還是一般 function, 用 define 還是 const, 連程式都還不知道寫不寫的出來, 就在煩惱這些小事不覺得想太多了嗎? 只要你寫的夠多, 最終就會知道是 define 比較好用還是 const 比較好用, 書上寫那個好的原因, 可能你根本就無法體會, 而一旦你有所體會, 也不用去管書上的建議了。
而混著用很好用, 我就混著用了。
除了這個, c++ 給了你很多個選項, printf, cout 我也常常混著使用, 因為我有時候覺得 printf 好用, 有時候覺得 cout 好用, 我知道這習慣不好, 請不要學我。但 global object ctor 裡頭不能用 cout, 我也只能用 printf(), 沒什麼選擇, 這是中招好幾次之後留下的深刻記憶。
c++11 在 iostream 直接加入了這行:
static ios_base::Init __ioinit;
「How can I ensure that global variables are initialized in the correct order?」介紹了 cout 是怎麼辦到的。
解決了 cout, cin 在什麼時候會被初始化的問題, 但我還是不太願意這樣用, 我不想對 cout/cin 有特例之外的處理, 一個原則就好, global object 的初始化是沒有保證的, 不要在 global object ctor 使用 global object, 這住這條原則就夠了。
令人驚豔的 boost 我也沒用過, 綜觀下來, 你應該不會覺得我是 c++ 高手, 我也的確不是 c++ 高手, 很多人都誤會我 c++ 很強 (這是我的平凡之其五), 但我還是用 c++ 寫了讓人覺得還蠻厲害的程式。
- simple_os - 呃 ... 這不是用 c++ 寫的不算
- simple_compiler - 目前只是 interpreter, 用到的 c++ 特異功能只有 class, c++ 標準程式庫, range base for, auto 不算特異功能, 但你不會認為這個東西很好寫吧!
- simple_stdcpplib - 因為寫了容器 (list, vector, map), 我用了 template function/class, 這個 c++ template 真是難死我了。
- simple_scheme - bj4
- simple_gui - 我參考了《事件式驅動式程式設計》, 以 MVC (就是現在 web 程式上很熱門的 MVC) 完成了一個文字模式的 window system。
我沒像劉未鵬《我的C++學習歷程(old)》這麼努力學習 c++, 我只有看書, 沒有去看 stl/boost/others 的程式碼, 這是一個學習的敗筆, 幾乎只有學生時期才有這樣的時間, 看別人的程式碼是很好的練習, 因為上班後就知道要改很多前人寫的程式碼, 看懂他們很重要, 好 code 要看, 爛 code 更要看, 要不然你怎麼改得動。別期待能看到好 code, 那是上輩子修來的福氣。而且能在爛 code 上持續加上新功能, 不是也有另外一番成就感嗎?
我的學習過程在《 [嘴炮] - c++ 之電腦語言之爭》描述過, 我花在看書的時間太多了, 不應該這麼做, 應該要把時間花在真的寫程式上, 不管是寫在紙上還是在電腦上, 總之去寫就是了。
simple 系列是我亡羊補牢之作。要是能在學生時代完成這些, 現在寫的就是 complicated 版本了。
紙上得來終覺淺, 絕知此事要躬行。 |
ref:
C++, Farewell~
https://github.com/kasicass/blog/blob/master/cpp/2018_11_23_farewell_cpp.md
感謝分享
回覆刪除謝謝
回覆刪除