如何提高 C/C++ 編程能力?

編程的牛人,平時都做哪些編程題目,具體的網站,或書籍?平均一個題目要花多久?

我之前自己自學了很多基礎理論東西,看了the c programming language ,c++ primer ,深入理解計算機系統等...平時數據結構課的實驗都做,程序都寫。現在是不知道接下來要幹嘛,接著學什麼?看什麼書?我想在linux下編程這方面發展。


很多答案都談到演算法的重要性,我的答案主要集中在C++上,只是一些個人經驗。

其實我以前也有這樣的困惑,感覺完了不知道怎麼用。而且我也不是學計算機的,也沒有從事相關工作,所以大概有十年的時間都沒寫什麼程序。最近因為想做點東西,所以又重新開始寫。

剛開始用的是python,比較好學。但是因為神經網路計算量太大了,用python效率不太夠。後來用matlab寫,matlab也比較方便,矩陣運算優化得很好,但是太耗內存了,我的破機器沒法處理那麼多數據。於是後來就開始用C++。

C++是相對而言比較容易出錯,我一般碰到問題就去stackoverflow查查,基本上都能找到答案,如果沒有現成的,就問一下,一般半小時以內就會有人回答,所以總體還是比較方便的。

C++在內存管理上有比較大的靈活性,很多時候程序的效率可以從這裡發掘出來。同樣的演算法,因為可以方便的管理內存,所以效率會有很大提高。比如使用指針可以減少不必要的變數複製,但是指針也容易出問題,所以有些時候能有替代的,就用替代的,比如傳遞參數時可以是引用,遍曆數組的時候可以用迭代器等等。這些都可以提高內存使用效率,同時安全性也更高。這樣的問題在python等語言中都是不需要考慮的,因此在大量數據和計算的時候,python也很難達到C++的靈活性和效率。

C++的另外一個特點是語法特徵很豐富。因為很豐富所以也很容易搞錯。我自己給自己設定的原則是,如果有簡單的特徵就不用複雜的特徵。比如我很少會用到面向對象的繼承,因為繼承往往會讓類的層級變得很複雜,這時候如果用模板或者友元可以簡化問題,那就不用複雜的。不僅是功能要解耦,還要數據類型和演算法儘可能分離開,設計好介面,無論使用C++中哪種範式的語言特徵都應該以這個為目標。

光自己寫也不行,還是得看看高手的作品。一般開源項目都比較複雜,水平也參差不齊,文檔也不一定完善。我自己學習的過程中看的是SGI STL的代碼,感覺還是很厲害的。侯捷有本書可以作指引。STL作為一個基礎庫,既要功能強大,又要提高效率,這是多麼難的事情。以我這樣的菜鳥水平,只能用大開眼界來形容了吧。

另外,演算法雖然很重要,但是很多實際項目中,演算法基本是固定的。再比如大規模計算時,要使用到GPU,很多精妙的演算法完全用不上,反而越簡單的演算法越容易並行化。

所以我感覺,學習的重點除了演算法,還要注重程序設計簡潔清晰,內存使用合理,如果有必要還可以針對具體硬體進行優化。

大概就這麼多了。。


OJ(online judge)

http://en.wikipedia.org/wiki/Online_judge

在國內比較流行的一般是zoj,poj

比較冷門的有hust,hdu什麼的

一般在zoj上做到900題+的,則可以認為是全國級別的acmer了

code forces

最近流行的coding contest網站,賽制不錯,1個半小時3道題目,採用和aa對戰平台類似的分數制度,一般1900+可以算world final級別的

top coder

老牌的coding contest網站,得分方式和aa平台類似,除了coding和submitting,還有challenge環節,是挑出別人的bug給自己增加得分的。一般來說2000+算是world final級別的。

除了上面幾個常規的練習演算法數據結構的網站外

百度astar,有道難題

是國內程序挑戰賽,一年一次,適合c,c++,java程序員,賽制和OJ類似

國外的有

top coder open, google code jam

ps:acm world final, top coder open 和 google code jam被稱為三大coding國際大賽,從古至今得過大滿貫的只有教主acrush一人,同時教主還是top coder上迄今為止最高分保持時間最長的一位。


我想寫點我的學習歷程,雖然我現在水平也不怎麼樣:

當年我學C++的時候,我已經學會了彙編和matlab("會"指可以使用這兩個語言做些工作),

還是對編程還是有一定理解的,C++的學習,看過4-5本書,寫了些簡單的程序,

自以為掌握得不錯,然後開始寫一寫稍微大型一點的程序時,C++這個語言完全讓我感到

非常的無助和崩潰,有一段時間我感到我設計的每一個類結構都如此之蠢,我寫的每一個new都會

泄露內存,每個演算法都那麼低效,每寫一行語句都是未定義行為......

直到有一天,我開始研究一個開源類庫,我比較幸運,那個類庫的東西我正好用得到,而且類庫本身

不太大,也沒有隱晦的設計,在研究了它的設計,再試圖自己重現它的設計之後,我彷彿一下撥開了

雲霧看到了一些問題的本質.這比我做多少道題,看什麼書,寫多少"學生管理系統"都好的多得多.

收穫非常大.


我以前寫過這樣一篇文章,感興趣你可以看看。http://www.perfect-is-shit.com/how-to-learn-cpp.html,C++只是一門語言,一個工具,不要站在C++的角度去想C++。


有一些比較好的開源框架可以學習,比如:

  • Webbench

Webbench是一個在linux下使用的非常簡單的網站壓測工具。它使用fork()模擬多個客戶端同時訪問我們設定的URL,測試網站在壓力下工作的性能,最多可以模擬3萬個並發連接去測試網站的負載能力。Webbench使用C語言編寫, 代碼實在太簡潔,源碼加起來不到600行。下載鏈接:LippiOuYang/WebBench · GitHub

  • Tinyhttpd

Tinyhttpd是一個超輕量型Http Server,使用C語言開發,全部代碼只有502行(包括注釋),附帶一個簡單的Client,可以通過閱讀這段代碼理解一個 Http Server 的本質。下載鏈接鏈接:LippiOuYang/Tinyhttpd · GitHub

  • cJSON

cJSON是C語言中的一個JSON編解碼器,非常輕量級,C文件只有500多行,速度也非常理想。

cJSON也存在幾個弱點,雖然功能不是非常強大,但cJSON的小身板和速度是最值得讚賞的。其代碼被非常好地維護著,結構也簡單易懂,可以作為一個非常好的C語言項目進行學習。

項目主頁:cJSON | SourceForge.net

  • Libev

libev是一個開源的事件驅動庫,基於epoll,kqueue等OS提供的基礎設施。其以高效出名,它可以將IO事件,定時器,和信號統一起來,統一放在事件處理這一套框架下處理。基於Reactor模式,效率較高,並且代碼精簡(4.15版本8000多行),是學習事件驅動編程的很好的資源。

下載鏈接:http://software.schmorp.de/pkg/libev.html

  • Memcached

Memcached 是一個高性能的分散式內存對象緩存系統,用於動態Web應用以減輕資料庫負載。它通過在內存中緩存數據和對象來減少讀取資料庫的次數,從而提供動態資料庫驅動網站的速度。Memcached 基於一個存儲鍵/值對的 hashmap。Memcached-1.4.7的代碼量還是可以接受的,只有10K行左右。

下載地址:memcached - a distributed memory object caching system

  • SQLite

SQLite是一個開源的嵌入式關係資料庫,實現自包容、零配置、支持事務的SQL資料庫引擎。 其特點是高度便攜、使用方便、結構緊湊、高效、可靠。足夠小,大致3萬行C代碼,250K。

下載地址:SQLite Home Page 。

  • redis

redis是高性能鍵值對存儲系統antirez/redis · GitHub

查看C++框架整理:值得推薦的C/C++框架和庫


前期刷OJ 後期做項目

ACM出身的,轉型項目輕而易舉,代碼質量一般人難以匹敵。

而純項目出身的人,水平則很一般了。

以上是親身體會(身邊同學很多,我總結出來的)。

所以,想做真正的程序員而不是代碼工,先靜心學演算法、做題吧。


項目和題都很重要。

為什麼要有繼承封裝?相信做了項目之後比看書的體會更深。

當然做題也很重要。但做題最終也是為了做項目。


C語言是系統級語言,推薦閱讀《深入理解計算機系統》,可以讓你對整個計算機體系結構和工作原理有更深的認識的同時從系統的角度加深對C語言的理解。


看你的「編程能力」指什麼了……如果你是指那種比賽能力,那請摺疊

如果指糊口混飯吃的那種能力,那就不要做題目了,不管哪個網站哪個論壇都沒用,你需要做「東西」,而且最好是跟別人合作做「東西」。

寫個app啦,做個網站啦,都是不錯的起點,也有很多網站上發布那種「活兒」的,真有空去接兩個。

如果想訓練c++你就儘可能用c++來寫

做個類比就是編程是木匠活,c++就是某種木工刀,光做些方塊,木條是沒用的,必須做出個桌子凳子來你才能體會木匠活的精髓

差別基本等於過家家和過日子的差別


做題到一定的程度之後應該考慮做一些實際項目或者參與一些開源項目,畢竟做題是鍛煉我們解決問題的能力培養寫程序追求性能極致的習慣,但是這些東西本身不能創造價值只有將這些做題得到的能力應用到實際的項目中才能體現自己修鍊的價值。

有ACM程序設計經歷的人一般都希望自己以後的工作是避開繁重的重複編碼將精力集中在程序性能、表現代碼的巧妙設計和優雅等。鑒於此可以考慮去做一些編譯器相關(實現一門語言的編譯器)、3D遊戲引擎的開發實踐。在linux下可以去找一些高質量的開源項目加入到開發社區。和大師交流(前期可以只欣賞)貢獻自己的專業技能。一個小功能將性能優化到極致、代碼優雅到極致便是藝術。在沒有進入應用開發之時保持這份對技術的追求日後定能有所成就。

本人目前從事遊戲開發,目前使用cocos2d-x遊戲引擎。感慨工作之後因國內普遍的逐利意識浮躁的行業氛圍,對代碼的藝術追求漸漸的因頻繁的需求修改和緊迫的項目周期而讓步。但是我們何時忘記了自己最初的理想?堅持自己的追求,保持對代碼性能的壓榨。 很想有一天能搞做到真正意義上的技術研究崗位,從事底層標準的的制定和開發。希望樓主一路走好- -


http://blog.csdn.net/bruce0532/article/details/7382673「藉助開源項目,學習軟體開發 .「藉助開源項目,學習軟體開發」 CSDN上一篇很好的博客!去看看吧~


怒答!

從不會C/C++到2W來行,到億級請求量的查詢項目

其實很簡單,書我只推薦一本

《高質量程序設計指南:C++/C語言(第3版)(修訂版)》

其次掌握調試工具gdb、學會寫makefile等

然後掌握C/C++項目的結構規範

然後你還需要一個資深的師傅幫你hold全場

然後剩下的就是努力了

PS.答主有深厚的Java功底和還過得去的PHP功底


要明白程序是什麼?程序其實就是一些機器指令集合,而機器指令與彙編語言是一一對應的。學習c++要多從實現的角度去想,即c++編譯的彙編怎麼樣?虛函數怎麼實現?虛函數的順序怎樣?不顯式調用虛函數名可以怎麼調用虛函數?多重繼承如何實現?dynamic_cast如何實現?把自己想想成c++的設計者,想像成編譯器。另外就是用c++做設計。如何實現com?各種設計模式以及其優缺點和使用環境。研究實現最好的方法是看彙編代碼;研究設計要多做項目,打磨代碼,不斷改進中能力就有了,可以看看設計模式這本書。


可以看看軟體設計,設計模式之類的,c, c++的很多人容易陷入細節而忽略了軟體的宏觀


編程語言也是一種語言.語言的作用就是表達人的想法.所以如果想提高對於語言的編程能力,首先在"想法"上有所提高.

建議先看一下宏觀的書,強烈推薦計算機程序的構造與解釋.還有一些設計模式,以及你現在編程所針對領域的一些專業知識.


建議題主多看一些有名的開源代碼,個人推薦比如FreeDOS這些比較底層的,開源代碼不僅含金量很高,還能使你能了解框架系統的構成,同時等於直接讀懂大牛程序員代碼的精髓,提升自己的看代碼和寫代碼的水平。長期做到會使人養成一種能看懂代碼好習慣,從而受益匪淺!祝題主在碼農路上一路順風!


分頁阅读: 1 2