如何系統地學習 C++ 語言?

學了一學期c++ 但對編程 感覺還是無從下手 可能是練得比較少吧 現在想好好學 c++ 該怎麼學呢


由於我大一也陷入過迷茫,也走過一些彎路,那時候學不會直接記憶代碼之類的事情我都干過,我也希望我的這些經驗可以對你有所幫助。

首先是一本好的C++書籍(Accelerated C++, C++ Primer),然後以及盡量多的完成書籍的習題,可以幫助完成C++語法的學習。雖然前面的書籍涵蓋了標準庫,但是不夠完善,這個時候你可以選擇在線查閱C++標準庫這種泛型的學習方式,也可以選擇閱讀《C++標準庫》的方式進行學習。通過這樣的步驟,你應該可以完成C++的初步學習了。

然後,由於C++是一門系統級語言,我想你需要到大三學習操作系統的時候,才會明白棧與堆、內存管理等更深層次的含義。但是,在明白這些概念之前不會妨礙你利用C++做一些事情,比如寫一個簡單的XML Parser。這個時候,你應該會發現很多問題,如效率,代碼規範等,這個時候,你可以研究Effective C++,Google C++ Code Standard等,只有自己犯了錯,回過頭反省才會更加深刻。

隨後,你可以更加深刻的去思考C++,你需要閱讀《The Design and Evolution of C++》。這本書的閱讀,會教會你很多,是對你影響最大的C++書籍。如果你對C++編譯器的一些細節有興趣,深入C++對象模型可以推薦。如果你對STL的一些實現有興趣,可以去翻翻STL源代碼(很多人推薦STL源碼剖析,但是我沒有閱讀過,我沒有辦法發表是否應該推薦的觀點,列出來供你自行判斷是否應該閱讀)。

到這一步驟,我想你應該可以稱為C++ Programmer了,剩下的就是實踐中發現問題,然後補足自己。

此外,由於C++博大精深,應用的範圍多如牛毛,特定方向所需要的知識未列舉。比如你要研究Android的NDK什麼的,那就是屬於你後面的事情了。

===================Update============================================
說實話,我也不知道這一條為什麼突然火了,發現突然有很多的贊。其實正如第一句而言,這是我走過來的經驗,我不能說這就是權威的(甚至不能說是正確的),而當初回答這個問題也是以我走過來的經驗來回答一個初學者的困惑。而這位初學者的困惑在我大一的時候也出現過,所以一下就引起了我的共鳴,我也只想把我的經驗說出來希望可以幫助提問者少走一些彎路而已。至於這樣學習的C++夠不夠,我想我按照這樣的路線學習,可以做到我有能力去IBM寫C++編譯器,那麼我想對於就單純題主所提的C++語言方面來說應該已經足夠了。誠然,計算機的世界不僅計算機編程語言,與之相關的還有操作系統、數據結構、編譯原理、計算機網路等知識,但是,我想我們可以再開另外一個問題。同時,既然別人問了如何學C++,你讓別人學Java、Python等,或者說C++大坑的,我覺得這種回答其實挺不好的,因為別人問什麼,你老實認真答什麼就好了,何必把自己的意願加在別人的身上呢。


C++ 需要不斷地練習 —— vczh


先說一個觀察到的現象:一個應屆畢業生不論其上學時學過什麼語言,只要肯努力,一般在項目里做一個月後,基本可以具有自己寫點小東西的能力了。當然這時候寫的東西談不上好,不過基本算得上入門,可以做到基本語法沒問題,不會被IDE的使用卡住。


從個人學習編程語言的經驗來看,學習過程中最大的問題是:沒有實際項目經驗的新手過渡在意對編程語言的語法學習,不停的啃書本,肯德頭暈眼花。一個類的成員函數就有無數的門道:重載、覆蓋、虛函數、純虛函數等等。看完覺得可神奇了了,然後不斷咒罵怎麼搞得這麼複雜,吃飽了撐的。

程序語言是用來解決實際問題的,是一種思維表達。語法只是附屬品,只是計算機這個電子設備的使用方法。不論看了多少遍使用方法,最後還是要落到使用計算機這個環節。不看一下別人怎麼用,自己再實踐一下,使用方法永遠是紙面上的幾個字,永遠不知道為啥有這麼多的功能,比如那些重載、覆蓋、虛函數、純虛函數顯然不是沒事兒找事兒硬發明的,每一樣都是要解決一個實際問題,當你了解他們為了什麼而存在的時候,自然你會覺得「呦,還不錯哦」。


舉個不太恰當的例子,寫代碼和寫作文一樣。當沒寫過作文前,覺得寫作文很難,不知道如何開始。當用大白話寫完第一篇作文的時候,覺得寫作文也還行,也還能寫。寫第一篇作文的時候一定很在意語法,當用大白話偶爾夾雜「一望無際」、「萬里無雲「這種美妙辭彙寫幾篇記敘文後,會覺得寫作文也就是那麼一會兒事兒。雖然讀過幾篇大師作品以後再看自己寫的還是覺得挺噁心的,不過好歹可以寫作文了,至少寫個日記門沒問題。也許再經過不斷修鍊,自己也能成為辭藻華美的大師。


題主現在遇到的問題是怎麼能開始寫大白話的程序。


我的建議是,學習編程要從「抄」和「改」開始。你可以沒吃過豬肉,但你得先見過豬跑。你可以沒寫過作文,但你要想寫作文得先讀過文章,然後摘抄人家的文章,把「小紅」改成「小明」,把「買冰棍兒」改成「買糖球」等。改幾篇之後自然就有感覺了,覺得自己也可以把「小紅買冰棍」的故事,改成「小明買糖球並幫媽媽買了醬油」,再改成「小明騎自行車買糖球並幫媽媽買了醬油」,再改成「小明騎自行車買糖球並幫媽媽買了醬油,路上碰到了小紅」,再改成「小明騎自行車買糖球並幫媽媽買了醬油,路上碰到了小紅,對小紅說晚上一起寫作業吧」。


從Copy和Paste開始不是什麼罪過。


第一步:放下書本,找一個設計優秀的C++代碼庫或者應用程序。可以是一個小型的引擎(例如Ogre的超早期版本、一個網路庫),或者是你感興趣的其它領域的優秀代碼(例如一個簡易的IM程序)。一定是大家認可的,設計優秀的代碼。


第二步:自己拿這個庫仿照已有代碼寫一些真的有趣的應用程序。這些好的代碼庫一般都有簡單Tutorials,按著Tutorials一步一步的跟著寫,學會調試,然後不斷擴展。比如如果是Ogre你就寫一個超小型遊戲,如果是網路庫你就寫一個小型IM。

第三步:在你寫的足夠多以後就去看看代碼庫本身的代碼和設計,遇到不會的就翻書就問別人。


第四步:拿起書本,找那基本大家公認的「解決實際問題」的C++書來看,比如Effective C++那些,但不要看C++ Primer這種大部頭,這種是「工具書」,有問題去查,沒問題就放那放著。這時候你經過第一步已經對C++語法基本熟悉了,並且經過第二步你會碰到一些實際問題,所以看一些解決實際問題的東西會很有效率,認識也會很深。


第五步:按著上面看書看到的知識,去修改第二步自己寫的東西。


第六步:如果還有時間就按著你的想法去修改一開始你看到的那個庫,把它改成屬於你的庫。這一步很可能是失敗的,也是有始無終的,但拆過優秀的東西才能真正明白別人寫的為啥優秀。這個過程學習的不止於C++還有設計和專業知識。


一般實習生進公司不用2個月C++至少寫點小程序沒問題,原因就是他終於開始寫了,而不是繼續看書!

不推薦一開始就看書特別是大部頭的書,因為對基本的東西都沒什麼認識,人家說的能解決什麼問題也不知道,看了也是白看。


2016/9/6

這裡強調的是要開始寫代碼,並不是說一點基礎知識都沒有就開始寫。我覺得大學課本能看懂就可以開始寫代碼了。


不了解C++的人先認識一下C++(系統學習材料附後)。

Effective C++ 3e 條款1:視C++為一個語言聯邦

為了理解C++,你必須認識其主要的次語言。幸運的是總共只有四個:

  • C。說到底C++ 仍是以C為基礎。區塊(blocks)、語句(statements)、預處理器(preprocessor)、內置數據類型(built-in data types)、數組(arrays)、指針(pointers)等統統來自C。許多時候C++ 對問題的解法其實不過就是較高級的C解法(例如條款2談到預處理器之外的另一選擇,條款13談到以對象管理資源),但當你以C++ 內的C成分工作時,高效編程守則映照出C語言的局限:沒有模板(templates),沒有異常(exceptions),沒有重載(overloading)……
  • Object-Oriented C++。這部分也就是C with Classes所訴求的:classes(包括構造函數和析構函數),封裝(encapsulation)、繼承(inheritance)、多態(polymorphism)、virtual函數(動態綁定)……等等。這一部分是面向對象設計之古典守則在C++ 上的最直接實施。
  • Template C++。這是C++ 的泛型編程(generic programming)部分,也是大多數程序員經驗最少的部分。Template相關考慮與設計已經瀰漫整個C++,良好編程守則中"惟template適用"的特殊條款並不罕見(例如條款46 談到調用template functions時如何協助類型轉換)。實際上由於templates威力強大,它們帶來嶄新的編程范型(programming paradigm),也就是所謂的template metaprogramming(TMP,模板元編程)。條款48對此提供了一份概述,但除非你是template激進團隊的中堅骨幹,大可不必太擔心這些。TMP相關規則很少與C++ 主流編程互相影響。
  • STL。STL是個template程序庫,看名稱也知道,但它是非常特殊的一個。它對容器(containers)、迭代器(iterators)、演算法(algorithms)以及函數對象(function objects)的規約有極佳的緊密配合與協調,然而templates及程序庫也可以其他想法建置出來。STL有自己特殊的辦事方式,當你夥同STL一起工作,你必須遵守它的規約。

- 要系統學習C++,自然離不開學習資料。。。

系統學習之

  1. C++ Primer 第五版 (豆瓣) Stanley B.Lippman
  2. 可不看的書:The C++ Programming Language(新手未必參透),
    Essential C++(lippman的入門小書,不夠系統)

規範使用之

  1. Effective C++ 第三版 (豆瓣) Meyers
  2. Effective STL (豆瓣) Meyers
  3. 可不看的書(講解都遠不如Effective系列細緻,並且和以上兩本有相當可觀的重複條目):
    C++ Coding Standards(中譯名:C++編程規範 ),
    Exceptional C++(系列)

分類學習之

1. C++標準程序庫:自修教程與參考 (db) Nicolai M. Josutti STL使用必看!
(先學會怎麼用,對照Effective STL)
2. STL源碼剖析 (豆瓣) (看看容器、迭代器、演算法、函數對象乃至分配器的實現技巧)
3. 超越C++標準庫:Boost庫導論 (豆瓣) (Boost有比較完善的doc。可不看的書:《Boost程序庫完全開發指南》有點啰嗦)
The Boost C++ Libraries 第二版(Sept. 2014)
這本書也非常實用,附帶講解,適合入門!第二版基於 Boost 1.55.0 和 1.56.0 。第一版的中文翻譯:Highscore - Boost C++ 庫
Boost.Asio C++ Network Programming(一本很好的網路編程入門小書)
4. SGI STL Programmer"s Guide (STL的話可以參考SGI的編程指南)

後續:

  1. Effective Modern C++ (豆瓣) Meyers新作!新的C++特性,必看啊!
  2. More Effective C++ (豆瓣) Meyers (這本書沒有再版 裡面部分內容在Effective C++ 第三版中有提及,所以可以放到後續里再看)
  3. C++Templates (豆瓣)
  4. C++設計新思維 (豆瓣) Andrei Alexandrescu

- 要系統學習C++,離不開敲代碼(呵呵)

閱讀書本,查看文檔,實踐項目這些都是學習的通用手段,每個人都明白。要訓練的是讓自己更為高效的掌握這個輸入輸出不斷迭代的過程。系統掌握一門語言,其實也挺難的,有側重的掌握功能構件,循序漸進,一一擊破也許更為恰當。

不看書不看資料肯定是不行,你畢竟要學習的是C++啊,不可能按照別的語言習慣去寫,不可能只局限於實現功能,特別是C++還提供了這麼多精彩的入門與深入的學習資料。

最後,感興趣的可以搜搜這篇文章:
「典型的C++ 程序員成長經歷 」


在這裡以一個非計算機專業學生的角度從C++書籍的角度補充一下現在排名第一的答案。

我是一名自動化專業的學生,可是迷戀C++編程再加上購書癖,目前大約將國外經典C++書籍全部買完了,沒有全部詳細讀完,但是對各本書的內容及所處的層次都比較了解。

這裡單純講【看書】方面的總結,不包含項目實踐方面。

這裡先補充一下第一名回答中沒有直接提及的,但也是學習過程中很重要的,一個關於C++學習的分類,兩個大方向:面向對象編程(OOP)和泛型編程(GP)。這是兩個最基礎的方向,不過如果單純抱著一本國內常見的C++入門書籍看的話,很容易將後者忽略(國內入門書籍過重得介紹C和C++中共有的部分和OO部分,極端忽視GP部分,這可能和GP更多地用於函數庫的編程而OO更貼近大部分人實際工作的原因有關吧(&>__ 手機碼字,英文書名因為方便辨識,書名號不寫了哦(&>_

那就先從OO方面開始吧。
入門書:首先是兩本如同《辭海》般詳細的神書:The C++ Programming Language C++ Primer,這是兩本幾乎完全涵蓋了C++所有特性的書籍,就不做過多介紹了;另外一本同樣超贊的Essensial C++,可以看做是一本C++的《新華字典》,也就是上述兩本的的簡化版;以上3本適合所有同學看,不管是有還是沒有C基礎的同學,尤其是Primer第五版,隨著Moo大神的加入,將Accelerate C++的寫作風格帶入,呈現出了一種跟第四版完全不同的風格,另外就是C++11標準在第五版被涵蓋並放在了醒目的位置,也是超贊的(&>_

進階書:那就不得不提主席大人和他的好基友Meyers的兩個著名系列:Excptional 和 Effective系列了,前者包含3本:Excptional C++, More Excptional C++和Excptional C++ Style(中文版叫C++編程剖析),難度逐漸加深。主要是談工程方面的細節和經驗;在這個開始讀這個系列之前,有必要將Effective 系列中的兩本Effective C++和More Effective C++讀一下,尤其是前者,可謂"C++ 程序員必讀的第二本書",這個系列是講述編程風格的。這兩個系列讀完後可以看看(也可以不用看)《C++編程規範》,這可以說是上面兩個系列書的總結。

其實到此,偏OO方向的書也差不多介紹到這裡了,之所以到進階就結束,因為這方面確實是一些很實在的技術,在結合模板比較少的情況下,很少有所謂的"奇淫技巧"。不過在此要專門推薦一本OO方面更高層次的書 Inside the C++ Object Model,詳細地討論了對象的構造、生存、釋放等問題,不過對編譯器不熟悉的同學看的話可能就比較吃力了(&>_

接下來就介紹GP方向的書籍。
大部分GP的書籍都是以C++最核心的庫STL作為載體來編寫的。
入其實從學習GP開始,就不能算作是C++學習的入門了。不過因為分得比較細,還是按照三個層次來介紹吧。

入門書:個人認為沒有入門書(&>_
進階書:C++ Templates,模板學習的聖經,全面地介紹了模板的各個方面;Effective STL ,meyers的Effective系列的第三本,講述了STL方面編程風格,也介紹了實際編程中STL庫中一些容器和演算法的用法和誤區;Generic Programming and the STL,講述了泛型編程的核心思想和各種泛型組件(以STL組件為例)。

深入書:《STL源碼剖析》,從源代碼的角度分析STL中各種容器和演算法的實現,【強烈推薦以這本書代替其餘任何一本C++數據結構書的學習(前提是如果有信心有毅力學透的話),因為侯捷老師說任何一個C++學生寫出來的程序在SIG STL面前只能算三流程序,不妨多看看STL源碼】;最後一本則是Modern C++ Design,這是一本充滿了"奇淫技巧"的書,用泛型的思想結合模板寫出足以讓任何人都吃驚的代碼——原來還可以這樣寫。不過這本書中內容的價值則可能是仁者見仁了——一般工作中基本用不到(&>_

除開GP和OO這兩個方面,另外還有兩本書推薦給大家。一本是API Design for C++,顧名思義講述如何編寫高質量的API介面;另一本是《提高C++性能的編程技術》,講述一些提高程序效率的技巧,讓你知道C++同C一樣高效。Ps.這本書結合Effective系列和Excptional系列一起看有奇效哦。

好吧,關於C++書籍的介紹就差不多到這裡了(boost,loki庫我了解甚少,就不敢妄作推薦了)~祝各位同學在書海中遨遊(&>_


/*************************************2015.2.13添加******************************************/
這裡推薦兩本比較難以區分偏重於OO還是GP的書。

C++ strategies and tactics(中文名《C++編程慣用法》):這本書的副標題叫「高級程序員常用方法和技巧」,其實別被這個副標題嚇住了:) 何謂高級程序員?不同的標準有不同的看法,在學習階段看看又何妨呢~這本書可以說是總結了在OO、GP、異常、重用等幾個方面的諸多知識,可以看做是增加了更多模板和重用知識的Effective C++,不過寫作風格則是與之迥異了~

Ruminations on C++(大名鼎鼎的《C++沉思錄》),C++界著名的技術伉儷Andrew Koenig Barbara Moo 傾力著作,PS.這本書最後還有孟岩老師和兩位作者的訪談錄哦~~(正好這個寒假又重讀了這本書,感覺這些技術經典真是讓人在不同的時期領悟不同的感悟)。這本書的風格和之前推薦的 Accelerate C++很像,也是以大量實際小工程、「課後作業」這類引人入勝的形式,避開講述C++繁雜的語法(也因為這本書本來就不是入門書),而直接羅列出C++中常用的技巧,諸如handle類,智能指針,函數對象等,不僅闡述了這些技術產生的原因、設計的思想,更是從源碼層次分析了這些技術的實現。個人認為,這本書配合前面提及的More Effective C++一書中後面那些動不動一個就有20頁之多的item一起看,將會有很大的收穫哦~


C++是一門用來「解決問題」的語言,如果你沒遇到需要用C++來解決的問題,你不會有太大的動力去系統的學習C++。
還是從發現問題開始吧,學點Python、Ruby之類上手快的語言,做點有用沒用的東西,等到哪天你發現遇到了一個不能解決的問題再回過頭來學C++也好,學Java也好,有針對性就容易出結果了。


這個問題,構勾起了我的回憶,那是一個漫長的的故事!

第一次讓我萌生「遊戲是怎麼做出來」的想法,是在我玩了n遍超級瑪麗之後。
那時我讀初一,或許是因為家裡窮,不能天天玩,所以想念的時間遠遠大於玩的時間。
除了念書,腦子裡一直在回放瑪麗的每一幀的動作,每一個細節。
漸漸的,我開始思考遊戲是怎麼做出來的了。
從當時開始,直到大學畢業,我身邊沒有一個對程序感興趣的人,但是,不少人也都聽說過那麼一點的。而我的優點就是不計場合地見誰就問,答案就是,遊戲是用程序寫出來的,程序有basic foxpro c,c是最厲害的,就像最上乘的武功。於是,就這麼開始了c語言的學習之旅。
我其實只一個很沒有耐心的人,在沒有人教的情況下,我很快就放棄了,因為書上的內容和遊戲,真的是八杆子打不著,完全找不到學習這些枯燥語法的意義。
從現在的角度來看的話,當時如果有一台電腦,或許故事就不一樣了。
就這樣過了2年的學業生活,我接收信息的範圍逐漸變廣了,偶爾的一個機會,c++這個字眼進入了我的大腦。對於任何一個人來說,對於新鮮事物的理解往往是錯誤的,可是神奇的是,往往是那種錯誤理解的一種某個點,能激發出超強的意志力和耐心去閱讀和理解枯燥的文字,而抓住我的靈魂的就是「類」。或許是從當時開始,從空白開始理解,想當然地去想像各個知識點,最終,腦子裡的類和書中的類開始出現了明顯的分界線。或許正是這段時間的想像,在我的腦海中建立了一個奇怪的面向對象的世界,以至於在十幾年之後第一次接觸「模板」時,感覺那麼的熟悉,就像多年未見的親人,好吧,這是後話了。
於是,我再次放棄,但是,我已經明白了一件很重要的事情:程序語言和遊戲就是距離很遠,很遠。於是,我的潛意識裡開始轉移重心,決定先弄清楚一個軟體是怎麼做出來的,因為那個時候已經普及win95,「軟體」對我來說已經是一個很具體很直觀的事物了。
c++的書籍,基本上都是以語法為主的,這對於興趣的培養並不是什麼好事,畢竟沒有多少人一開始就會對黑黑的控制台愛的死去活來,在我初中畢業時,vc++就是這樣乘虛而入的。
我還是沒有電腦,更準確的說,我並沒有尋求電腦,至於為什麼,天知道,生物電作用下的隨機結果吧。
vc++相對來講,對初學者來說,真的是友好太多了,一上來就是拖拖拽拽,一切都是那麼的直觀和完美,不需要去關心窗口是怎麼創建的,按鈕是怎麼響應滑鼠的,總之,在對應的函數里填上代碼,就可以了。如果,我來創建一個工程,拖出一個按鈕,應該在點擊的時候,寫些什麼來讓程序看起來有所反應呢?嗯,列印hello world吧。
軟體=控制項布局+程序功能
這就是我看了一個月書之後的結論。
到此,最感興趣的事情已經結束,那接下來呢?等等,我還是不知道遊戲是怎麼做的,我的天!
我突然得出一個一個結論:vc++只能做標準樣式的軟體,想要做相對花哨的遊戲畫面,還得用c++,於是,我再次拿起了c++的書。
人想要變,需要經歷很多事情,正所謂為量變引起質變。但是,量變不夠就想質變,那是只能是在夢裡。很快,我再次被枯燥的語法打擊地忘了為什麼要看這本殺千刀的書了。
高中的生活是忙碌的,我沒有太多的時間去反思。但是,人的本質是不會變的,一本書上的一句話引起了我的興趣:想要掌握c++,就要先掌握c需要語言,那一瞬間,c語言再次成為我崇拜的偶像,她是天使,是救世主,是我命中注定的另一半!
先寫到這裡吧,一直很想寫,就借這次機會回顧和記錄一下,待續^_^

--------------
當我再次翻開c語言的書時,不再覺得枯燥,內心深處感覺到它是那麼的簡潔和直觀只有變數 函數 結構體。
這種迷戀很微妙,雖然沒能讓我跨過那個門檻,但是,我已經初步建立了程序語言的概念。
大學,不幸的是,我沒有考上計算機專業,念的是機械系。幸運的是,有彙編和c語言課程,因為,我的專業是數控機床與技術。
大學3年,除了瘋狂玩遍幾乎所有的網遊外,還認真地學習了c語言和彙編課程,我身邊依然沒有喜歡程序的人,但是,我有了可以寫程序的計算機。
第一次寫的遊戲是中國象棋,我將所有的代碼全部寫在紙上,等到上機課,就輸入到tc中進行編譯,第一次編譯1000多個錯誤,花了1個多小時才改完,這次的成功編譯大大降低了我對編譯錯誤恐懼感。於是,一個控制台版的中國象棋就這麼誕生了。
但是,這不是我要的遊戲,超級瑪麗可不是控制台文字遊戲。於是我開始沉浸在圖書館,查詢圖形初始化的方法。
圖書館關於c語言的書真的很多,但是,我只在一本書中找到了通過系統介面將窗口初始化成640*480的方法。
(整個製作過程也是非常有意思,包括解決重新繪製企盼會閃爍的問題等,各種現在看來就是一個初學者通過各種奇葩的突發奇想的方法解決各類簡單的問題,有空再另外記錄。)
大學畢業,我的象棋還沒寫完。回到老家,埋在三伯家,用他家的電腦,花了3天3夜,終於完成了我人生中的第一個完整的圖形遊戲。
至此,我算是入門了。
然後呢?我得找工作了。
(待續)

---------------
【知識的圓越大,未知就越多希臘哲學家芝諾曾經將知識比喻為一個圓,圓周內是你所知道的,圓周外是你所不知道的。一個人所知越多,他的圓就越大,圓周所接觸到的未知就越多。因此,知識越多,知道自己不知道的也越多。"人掌握的知識就是一個圓,圓外是未知世界.掌握的知識越多圓越大,你所接觸的未知越多---困惑越多.學得知識越多越覺得自己無知.】
我鬼使神差地來到了上海,夢遊般地進入了一家電扶梯鏈條實業公司工作,這一切就跟散步時一樣,不知不覺走了很遠很遠,回過神時,已經工作了兩年,而我的腦子裡,始終有揮之不去的東西—編程。是的,竟然是編程,而不是做遊戲!
我的工作很簡單,使用cad繪製圖形並在標準範圍內標註尺寸和公差。工資不高,活也不多,有時間看書,有時間繼續在網吧玩網遊。在這兩年里,我用vc製作了類似鬧鐘等工具,為檢驗科製作了excel的自動化腳本,這個腳本讓原本需要幾個小時的工作變成了一個按鈕的點擊操作,以至於十年過去了,他們還在使用。
我住在公司宿舍,兩年來,生活平靜,沒有波瀾。
第三年的春天,java開始橫行,j2se j2me j2ee 等等鋪天蓋地,我順勢參加了java的培訓,一年的學習過程中,非常隨著地學完了附送的日語課程,用java仿了qq聊天工具,了解了「魔力寶貝」(在我的人生中和超級瑪麗一樣重要的遊戲)的文件格式,通過在網路上各種碎片代碼,組裝出了自己的「魔力寶貝」資源管理庫,在當時手上的nokia3310手機上還原了魔力寶貝的回合制戰鬥。
這一切,酸甜苦辣,什麼滋味都有過,為了解決魔力寶貝斜45視角的轉換問題,有一個公式是在我苦苦思考了2天後,睡覺做夢時解決的。
我開始尋思到遊戲公司體驗一下。
說實話,我沒有系統學過編程,甚至我沒有用過malloc。
【常人面向圓心,看到眼前一大片都是自己的圓,知道自己知道甚麼;可是,他們只能夠看到圓周的一小截,並且忘掉自己的圓其餘的邊界。】
由於非正統的學習路線,我的程序世界,有點扭曲,有點理想主義,有點不切實際,這些是缺點,但卻是我的財富,因為,我對編程產生了一種莫名的信仰。或許正是這種信仰,當我表達自己對編程的熱愛時,無論是語氣 表情 還是 動作,都會讓你相信,我沒有說謊,我是認真的。
同時,不得不承認,編程能力,我不及一個計算機系的大學畢業生。
我非常幸運地進去了一家小公司,正式成為了一名遊戲程序員。
現在我在公司已經工作8年,我的能力依然不算強,但是我有了自己的學習方法,大部分的程序問題,我都能獨立解決。
後面的故事,有機會再記錄。

在私信中看到一個問題:「
你好:
看了&<&<如何系統地學習C++語言&>&>帖子你的回帖後,我想問問你是如何抱有興趣的做C++這麼多年堅持下來的?


關於這個問題,我有太多的話想說,嗯,請給我點時間!

做任何一件事情,最難的就是堅持。
我一直在思考這件事,在編程這件事上,我為什麼沒有放棄過,卻一直抱有超乎自己想像的熱情。
這個問題在我有了小孩之後才想明白。

如果你不是一個喜歡下廚房的人,偶爾也會有興趣做一回豐盛的晚餐,就算從來沒做過,這一次也能很用心,無論是做給愛人還是自己獨享——因為有新鮮感。
但是,堅持一年、十年、一輩子,很難。
我們的媽媽卻做到了,大部分媽媽不是因為喜歡,更沒有新鮮感。
我認為那是責任,以及對家人的愛。
這是一種信念!

我在之前提到過 信念 這個詞,為了描述清楚這個詞的含義,我再舉個比較極端,甚至會讓你覺得我是一個不切實際的人的例子:
在視聽設備上,我崇拜喬布斯(也不僅限於他),更準確的講,我崇拜他的影響力和創造力,他改變了世界,畫出了一條歷史的分割線。
在遊戲開發和設計上,我崇拜暴雪公司(也不僅限於他),他將一個又一個特定類型遊戲推向成熟。
在遊戲製作工具上,我崇拜flash、rpgmaker、unity、unreal(也不僅限於他們),因為他們讓有想法卻沒有能力從hello world開始做遊戲的人開發出了成千上萬的遊戲。
在生活上,我崇拜我的媽媽,因為她以一人之力將我養大。

我從高中的時候就有一種信念,我相信遊戲製作可以變成一種比較簡單的過程,只要有想法,人人都能做,而不是苦苦研究n年後還感覺沒入門。
flash告訴我,可以的,你看,就像我。
嗯,是的,但是不夠。
後來,untiy說,我來彌補他的不足。
嗯,是的,已經很好了,不過我覺得還沒到頭。
ue4說,你看我,完美。
我驚呆了,太完美了。
但是,還有更好的!是的,你我都知道,這是必然的,還會有更好的,只是還沒有被創造出來。
下一個,可以是我——這就是我的信念,狂妄的不切實際的信念!

我的這種 信念 體現在生活的方方面面,這是我的個性,我相對比較偏執。

當我發現自己不理解矩陣的時候,我在那之後3年里,經常看關於矩陣的書籍,不管看不看得懂,我始終認為我可以懂,只是時候未到,但是,有一件事情是能確定的,不去看,不去學,必然不知道,3年後的某一個時刻,我突然就悟了。同樣的,四元數、群論等也是一樣。

我沒有學習方法,我把一切都歸結于堅持和積累,量變引起質變。

------------------------------------------

5年來,一直在思考一個問題:程序到底是什麼?C++又是什麼?

記得,剛進公司的時候,技術總監安排我改造ui引擎,實現類似wow的ui腳本框架,當時討論lua的時候,他的一句話困擾了我10年:lua是運行速度最快的腳本語言,因為它內部是通過寄存器實現的。

寄存器?好熟悉的名詞,好歹我的機械系課程里還有一門彙編課程,但是,理解他這句話,整整經歷了10年。

10年的時間裡,我每隔一段時間,就會覺得自己懂了,但是隨即又會變得模糊,困惑。每次談論起這個話題,他的核心始終都是這句話,讓我不得不相信,這句話的正確性。

人,總是後知後覺。

當你覺得自己理解的時候,請問,你真的理解了嗎?

10年後的今天,我終於理解了:他這句話的背後,隱藏了太多太多的細節,我不理解,是因為我們根本就不在一個水平線上。我不理解,那是應該的。

我突然意識到一件事情:重點不是我理解了,而是我有了可以理解它的能力。

現在,我很少會去試圖用具體的詳細的語言教會一個程序員理解某個概念,而是給他一個能夠引導他去探索的結論,因為,重要的不是這個結論,不是知道或者不知道,而是探索的過程中所積累的知識和能力。

終有一天,他們會站在一個更高的角度去思考問題、以及觀察過去的自己獲得更深的感悟。


我也才學c++沒多久, 有些小心得願意與你分享。

第一階段:我覺得先學好c,c語言是很多計算機專業的入門語言,而且c語言也很簡單,用c也能做點小事情,比如說刷演算法題,實現一個簡單的數據結構等等。

第二階段:等c語言基礎好一點了,開始學習《c++ primer》,可以跳過裡面的一些基礎內容,重點掌握這麼幾個概念:
類(包括:類的構造與析構函數,複製控制函數,重載的概念,多態的實現,類的繼承與組合, 操作符重載,友元等等)
模板
STL相關的容器(先不用去記那些函數具體怎麼用,先知道每個容器是幹嘛的,支持哪些操作)【後面慢慢補充。。】


第三階段:如果覺得上面的概念理解差不多了,可以看看c++11的標準。
然後再看看《C++標準程序庫》,《effective C++》 《effective STL》

第四階段:最後如果你到了一定程度了,就可以看看一些c++的進階書籍,比如《C++的設計與演化》,還有C++之父寫的那本書。

不過我覺得c++的語法複雜,不單單是靠看書能達到目的的,我也不推薦看C++教學視頻,一個字:練,最好找一個c++高手,遇到不懂的就厚著臉皮問,把自己寫的代碼給他看,讓你給你指出哪裡做的不夠好,然後你反覆修改自己的代碼。如果能跟著高手做項目那就更好了,勤快點改代碼,高手教你的絕對比書上教的更加實用。
注意:上面的所有階段都要不斷的編程,一邊學一邊連,千萬不可以只看書,不編程


推薦學一個帶界面的東西,比如cocos2dx和c++或者opencv和c++比較直觀,學起來比較有效率


沒必要系統學習。最好的做法是興趣/問題導向。你可以試著找到自己感興趣但又不是太容易的一個問題來寫個程序。寫完以後再寫一遍,第二遍的時候想一想,如果重頭來過,怎麼寫可以更好。光說不練不會有實質性進步。


師傅領進門修行在個人。

關於技術類的書籍很多,像 @藍色 提到的 Accelerated C++, C++ Primer。 @令狐臭提到的書單都很好。

這方面就不扯了。想在這給你介紹可以一起學習的一群人。

在coursera上,北京大學開設的互動課程

課程信息名稱:程序設計實習 / Practice on Programming
by Jiaying Liu 劉家瑛, Ph.D., 郭 煒

不得不說這門課講的很不錯!課程設有討論區,有不懂的可以在討論區與大家討論,學習氛圍很好,現在課程已經更新到第九周了,如果你是單純想學知識,快去學習吧。

授課大綱:
第1周 從C走進C++
第2周 類和對象初探
第3周 類和對象進階
第4周 運算符重載
第5周 繼承與派生
第6周 多態與虛函數
第7周 文件操作和模板
第8周 標準模板庫STL (1)
第9周 標準模板庫STL (2)
第10周 枚舉演算法
第11周 遞歸演算法
第12周 動態規劃演算法
第13周 深度優先搜索演算法
第14周 廣度優先搜索演算法

這是真理-&>學這個要多動手練習;


推薦Stackoverflow上的C++書單:
http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list
其中beginner級別的都很系統化。建議根據你已有的C++經驗選一個合適的級別然後隨便挑一本看(每個級別有至少一本有中文版),慢慢提升以後再看更高級別(beginner-intermediate-advanced)。


我覺得學好C++最簡單的方法就是放棄C++,C++是個無底洞,人生很有趣,也很有限,不應該花巨大的時間去學這個所謂的無所不能的C++,如果真想精通計算機,那麼學C++是完全錯誤的,應該先有紮實的計算機學科基礎(比如操作系統,數據結構之類的),打好基礎之後如果題主還是想學C++,建議學基本語法,之後的學習建議在碰到問題中進行,一邊做項目一邊學,好了,我的建議還是放棄C++,學好C,然後在學其他的語言,繞過C++這個大坑


看彙編,學習深入理解計算機系統。知道怎麼構造程序,二進位咋樣?

不要系統地看c++ prime還有市面上最多的c++ effective系列。尤其是後者,意義不大。c++ 屬於零代價抽象的編程語言,行為可推測。看書不頂用,多思考怎麼在硬體上執行的。

家中常備c++ programming language, c++ prime, c++ reference之一。

學習Haskell,用pattern match的角度理解template.

看看inside c++ object model,知道虛擬函數怎麼搞的

認真閱讀 more c++ idioms,這本書才是c++的最牛逼的書

不要聽知乎上大牛的瞎扯,因為他們是在是胡說八道。不給你推薦boost 或者
more c++ idioms的人基本上都是嘴炮。

還有effective系列只是給非c++程序員面試c++用的,太被高估了。


首先要明白,主流編程語言分為兩大類:一類是面向過程的語言,比如C;另一類是面向對象的語言,如python,java,c#,C++等。
——————————————————————————————————
1.建議先把C搞清楚,至少基本語法沒啥大問題,然後C++基本就是一些OO的思想加上C的語法(當然一些細節不太一樣)。
2.初學者極容易陷入cpp那浩瀚無垠的語法細節之中,建議先認真理解一些OO的基本思想,如:封裝,繼承,多態,運算符重載,類,對象等等,先把自己編程的思想從面向過程轉到面向對象,具體的語法細節前期不要糾結太多。
3.其實軟體涉及到很多學科,語言知識一門工具,初學者不要把所有的精力都投入到編程語言的學習上,多花點精力和時間學習操作系統,編譯原理,彙編,數據結構等等,系統的學習將來會有助於你的發展,否則,你可以code的很久很久,還是一個碼農。
4.編程時實踐性很強的東西,紙上得來終覺淺,很多時候你去面試,HR一句話「廢話不多說,放碼過來」,你就知道什麼是「讀書千遍,不如代碼一行」了。
5.不要僅僅局限於實現細節,等有一定的基礎後,建議看一些uml和設計模式的書籍,有利於向更高層次的發展。
6.不要僅僅在課堂上跟著老師的步伐走,一定要注意課下的自學,師傅領進門,修行在個人。
7.life is too short to learn cpp,不要沉迷於自己的那片小天地中,多鍛煉,多與人交流


我也提個學習建議,《C++ Primer》首先要過一遍,都是基礎知識,對C++有個全局認識,最好學習過程中 ,書本代碼都敲敲。然後《深入理解C++對象模型》這本書必看,看完這本書,就理解了C++對象在內存中是怎麼存儲,以及成員函數是如何調用。接下來是《STL源碼剖析》,了解標準庫中的容器和演算法實現~最後就是effective系列的幾本書,因為effective系列的書是教你如何更有效率的編寫C++~所以當你對C++有一定了解之後,是必須看的~語言掌握差不多之後,可以看看開源框架,我這裡推薦的是leveldb和muduo~最後自己試著寫個開源項目也就差不多了~這是我的一些小想法~


哥,你不學編譯原理,怎麼可能「系統地」學習任何一門語言?


二十一天C/C++入門(靠譜版——提綱)
第一天 學習軟體的基本結構:

  1. 順序
    一條一條依次執行
  2. 循環
    多次執行同一個程序塊
  3. 跳轉
    主要用於從循環中跳出
  4. 分支
    按條件執行不同語句塊

第二天 學習變數,變數類型。

變數用來保存一個值,而在C/C++這種強類型語言中,變數是有類型的。
變數類型:
整數包括 char, short, int, long, long long ,並且可以使用 unsigned 表示它是無符號的。
浮點包括 float, double

第三天 理解運算符,函數第四天 學習數組第五天 學習結構

將多個變數「綁定」在一起組成結構,以保存更複雜的數據結構。並且結構可以套結構,因此結構可以慢慢擴展。

第六天 學習指針、引用(重點)

用指針指向變數,你就能通過指針找到它了。我們可以更改指針,讓它指向不同的變數。
引用(C++特有)同樣指向變數,但不可為空(必須指向變數),而且不能指向別的變數,因此可以認為引用是變數的別名。

第七天 學習分配內存 malloc, 釋放內存 free

** 到目前為止,你已經能使用 C 寫程序了 **

第八天 學習類1

類是更複雜的結構,不光包含變數,也包含成員函數。把數據和方法封裝在一起,就是所謂的面向對象
進階知識點:繼承
C++ 中的類可以繼承,另一個基類或多個基類。繼承類包含基類的變數、成員函數。
** 學會new,delete對象 **

第九天 學習類2

虛函數、純虛函數、重載
C++中基類定義的虛函數可以被繼承類重載,當基類的成員函數調用被重載的虛函數時,將調用被重載的版本。使用指向基類的指針調用虛函數,同樣會調用被重載的函數。
純虛函數的沒有實現,因此在它被重載前無法不調用,附帶的,有純虛函數的類,也無法被直接實例化。

** 這裡叉出去看一本「面向對象」 的書,學習重要的面向對象的程序設計思想 **

第十天 理解宏

宏是一種操縱源代碼的魔法,通過宏定義,能幫助選擇我們需要的源代碼塊。

第十一天 理解模板是什麼

模板是另一種操縱源代碼的魔法,他僅僅針對類型。使用模板可以給不同類型編寫公共代碼。

第十二天 理解操作符重載

操作符重載可以視為特色的成員函數,當你使用操作符來操作對象,實際是調用了操作符重載函數。

第十三天 學習STL之容器

理解容器,及他們的特點

array 容器為定長,連續存儲,基本等同數組。
vector 為不定長連續存儲,可以按索引隨機訪問,並且尾部自由插入刪除。vector 是多數應用程序的首選序列容器。 若不確定要使用哪種序列容器,請首先使用矢量!
deque 和vector 特點類似,但支持在容器的起點和終點進行快速插入和刪除,但是不具備連續性。
list容器是雙向鏈表,在容器內的任意位置啟用了雙向訪問、快速插入和快速刪除,但是你不能隨機訪問此容器中的元素。
set 為排序二叉樹,僅是按升序排列每個元素的容器,值也是鍵。set的無序版本是 unordered_set,內部為哈希表。 他們能保證容器中的元素唯一。
map 等同set,但鍵和值分開,可以用鍵存取值。同樣,無序版本是 unordered_map.
** 這裡叉出去看一本《數據結構》 **

第十五天 學習STL之迭代器

  • 理解迭代器
    迭代器抽象了容器的存取,類似指向容器中元素的指針,通過迭代器,可以存取容器中的元素。

第十六天 理解 function 類,理解匿名函數(Lambda函數)。

演算法和回調會用到

第十七天 理解常用演算法

** 到目前為止,可以去寫代碼練習了 **

第十八天 寫簡單工程第十九天 寫中等工程第二十天 寫複雜工程第二十一天 學習模板偏特化等進階知識


以語言設計者的思路去思考為什麼要設計C++的種種語法與結構(有興趣的話可以讀讀這本C++語言的設計與演化 (豆瓣))。技術性地理解運行時的內存空間分配,堆棧結構。

提示:為了面向對象,為了「物化」。

整個語言設計圍繞的就是這一個核心,精髓在於多態,C++是面向對象的語言,但並不是說寫出類與對象、學會封裝就算面向對象了,面向對象是一種精神與意識。作為練習最好地就是反覆寫一個程序(比如說掃雷、五子棋),然後一遍一遍地看書,批判式地重寫,對照高手的寫法。

然後,三五年過去了。。

就醬~


轉自微博……

轉自微博……


推薦閱讀:

TAG:學習 | 編程語言 | 編程 | C++ | 編程學習 |