1. 程式人生 > >FFmpeg In Android -學習C/C++

FFmpeg In Android -學習C/C++

學習C/C++經驗

寫了多年C++,說一點自己的感悟。雖然自己近期沒有接觸C++了,但是畢竟學習的第一門語言就是C++,使用時間最長的也是它。回顧起來,它就像老朋友一樣,始終帶給我一份親切感。儘管自己距離精通C++還有太漫長的距離,但也從使用C++的過程中有了不少的收穫和感悟,在這裡分享一下。
C++的入門學習曲線相對高一點,但是如果循序漸進,不刻意追求那些奇技淫巧的話,其實還好的。
就我自己而言,我把C++看作是幫我組織和簡化程式碼的好助手,而不是一個有著複雜語法和號稱“最難掌握語言”的工具。
其實仔細想想,C++的語法並不是隨意制定的,而是有著嚴謹的體系,所以不能生硬地記憶。
如果能夠很好地理解和遵循這套程式設計思想體系(哪怕最開始的時候只是嘗試去依葫蘆畫瓢),就可以比較容易地寫出有著良好組織的程式碼。所以,語法不是給你帶去痛苦的,而是用來幫助你寫出更優秀程式碼的。
說到簡化程式碼,可以利用C++編譯器和標準庫來幫自己做很多事情,而不要什麼都自己去實現和解決。比如說,C++編譯器可以提供RAII、模板等強大功能,既能省下程式碼工作量,還能減少出錯的可能性,標準庫則更無需多言了。
所謂減少bug的最佳方式就是不寫程式碼,我的理解大抵如此。
C++相對比較麻煩而容易出錯的地方,一個是複雜繼承層次和關係,一個是記憶體管理,一個是多執行緒程式設計,以下簡單闡述一下自己的愚見。
對於複雜繼承關係應該儘量避免(其實良好的設計基本可以避免這種情況出現),可以考慮用組合關係來替代。當然,還是要順應領域模型,最好是有著清晰的對映關係,而不要為了組合而組合,那就過猶不及了。
對於記憶體管理,現代C++完全可以通過STL容器加上智慧指標的方案妥善解決。此時,程式碼裡不會再出現手動free的情況,很大程度上減輕了程式設計師記憶體管理的負擔。當然,STL或智慧指標要用好也不容易,特別要注意一些常見的坑(參見《Effective STL》)。
多執行緒程式設計則不僅僅是C++程式設計師要面臨的問題。對於C++而言,通常有兩種方式解決多執行緒資源訪問衝突的問題:一是利用RAII來加鎖和解鎖(針對跨執行緒操作的物件),二是讓同一物件或資源只在同一執行緒中進行操作。
再談C++的學習和應用。C++實戰大多離不開三類技能(不談及演算法):
一是C++本身內容的掌握,包括語法和標準庫等;
二是系統API的掌握,包括檔案系統、圖形介面、資料庫系統、網路程式設計等;
三是領域知識的理解,權且也把面向物件程式設計等思想和能力算在內。所以,這其實是一項綜合能力的培養和學習,並不僅僅是學會了語法就OK。
要想用好C++,我自己的一點經驗,首先要對語法有紮實的掌握,特別是一些細節和容易忽略的地方,不然就容易埋坑。當然,這不是說只有把語法全部掌握了才能開始寫程式,而是要在實踐中循序漸進,每實踐一個知識點就儘可能把對應的細節和坑弄清楚,這樣隨著時間和經驗積累,就能紮實地打好基礎。
此時,《C++ Primer》第5版可以作為案頭必備的參考書和工具書。同時,還要儘可能理解和掌握業界的最佳實踐,並運用到自己的程式碼中。這些最佳實踐怎麼來呢?
一是經典書籍,包括《Effective C++》、《Effective STL》等;
二是優秀的開源專案,我個人非常推崇陳碩的muduo庫,自己也從中受益匪淺;
三是不斷反思自己原來的程式碼,總結經驗教訓。
對於第三點,可以採用快速迭代的思路,不要惰於優化和完善原有程式碼,因為這是提升自己的很好的機會。再高一個層次,就是對於自己寫下的每一行程式碼,都很清楚這行程式碼在背後做了什麼事情,這樣對於自己的程式碼就有很好的掌控力。比如,呼叫虛擬函式的時候,使用STL容器的時候,儘管我們只是一個函式或方法呼叫,但其實在我們的程式碼背後還默默地做了很多事情。
從系統、語言、標準庫三個層面,我分別推薦《深入理解計算機系統》、《深度探索C++物件模型》和《STL原始碼剖析》三本書,可以從中找到答案。C++語言之父提到他設計C++語法的一項基本原則是向程式設計師提供儘可能的靈活性,但是這種多正規化帶來的靈活性和語法的複雜性也提升了團隊合作的難度,並且對團隊每一名成員的程式設計能力都提出了較高要求。一個簡單的辦法是通過專案約定來控制不同正規化的使用,儘量統一大家的程式設計風格和思路,這樣可以從語言層面控制專案的複雜度。
最後,談一下自己學習C++的一些體驗。剛開始學C++的時候,基本不得要領,寫出來的軟體雖然實現了對應的功能,但是健壯性和可維護性堪憂。被同事推薦後看了《敏捷軟體開發:原則、模式與實踐》,反思了以前程式設計的痛苦經歷和種種問題,算是第一次提升;
後來看過《深度探索C++物件模型》,對所寫程式碼背後隱藏的東西有了比較深入的理解,算是第二次提升;
再後來仔細研讀了陳碩的muduo庫原始碼,在實戰層面有了更好的參考,算是第三次提升。
雖然也看過其他很多書籍和原始碼,並且有著或多或少的收穫,但是對於自己可以稱作里程碑的節點,大概就是以上三個了。

學習書籍
C Primer Plus, C程式設計語言K&R第二版, C和指標, C專家程式設計, C陷阱和缺陷, C標準庫

C++入門:
C++ Primer Plus, C++ Primer、C++程式設計語言(The C++ Programming Language)、C++ 標準程式庫(The C++ Standard Library)、STL原始碼剖析,Effective STL;
C++中級:
Effectiv C++ 、More Effective C++,Think in C++ , C++沉思錄,
Exceptional C++, More Exceptional C++,泛型程式設計與STL、深度探索C++物件模型(Inside the C++ Object Model)
C++高階: <<C++演化和設計>>
系統: Linux系統程式設計,Unix系統程式設計,Unix環境高階程式設計, Unix網路程式設計, 資料庫系統等