您的位置:首頁>正文

學C++的過程中走了很多彎路?來,老司機帶你直線超車

現在很多小夥伴都在學習C++在學習的過程中難免遇到一些困難, 在各大網站論壇去搜索C++的學習方式。 但是在網上流傳的錯誤的C++學習方法一抓就是一大把。

為什麼會存在這麼多錯誤認識?主要原因如下, 同時小編推薦一個學C/C++的學習群627819188無論你是大牛還是小白, 是想轉行還是想入行都可以來瞭解一起進步一起學習!群內有很多乾貨和技術分享!

原因主要有三個

1、是C++語言的細節太多。

其它語言的細節也不少, 比起C++起來還是小巫見大巫, 就拿javascript來說, 作用域規則, 名字查找, closure, for/in, 這些都是細節, 而且其中還有違反直覺的。 但許多動態語言的程式師的理念我猜大約是學到哪用到哪罷。 但C++就不一樣了, 學C++之人有一種類似於被暗示的潛在心態, 就是一定要先把語言核心基本上吃透了才能下手寫出漂亮的程式。 這首先就錯了。

2、一些著名的C++書籍總在暗示語言細節的重要性和有趣。

C++書籍。 市面上的C++書籍不計其數, 但有一個共同的缺點, 就是講語言細節的書太多——《C++ gotchas》, 《Effective C++》, 《More Effective C++》, 但無可厚非的是, C++是這樣一門語言:要拿它滿足現代程式設計理念的需求, 尤其是C++庫開發的需求, 還必須得關注語言細節, 乃至於在C++中利用語言細節已經成了一門學問。

比如C++範本在設計之初根本沒有想到範本元程式設計這回事, 更沒想到C++範本系統是圖靈完備的, 這也就導致了《Modern C++ Design》和《C++ Template Metaprogramming》的驚世駭俗。 這些技術的出現為什麼驚世駭俗, 打個比方, 就好比是一塊大家都認為已經熟悉無比, 再無秘密可言的土地上, 突然某天有人挖到原來地下還蘊藏著最豐富的石油。 在這之前的C++雖然也有一些細節, 但也還算容易掌握, 那可是C++程式師們的happy old times, 因為C++的一切都一覽無餘, everything is figured out。 然而《Modern C++ Design》的出世告訴人們, “瞧, 還有多少細節你們沒有掌握啊。 ”於是C++程式師們久違的激情被重燃起來, 奮不顧身的踏入細節的沼澤中。 尤其是, 範本程式設計將C++的細節進一步挖掘到了極致——我們幹嘛關心涉及類物件的隱式轉換的優先順序高低?

3、是現代C++庫的開發哲學必須用到一些犄角旮旯的語言細節, 但注意, 是庫設計, 不是日常程式設計。 這些共同塑造了C++社群的整體心態和哲學。

最大的問題還在於, 對於這些細節的關注還真有它合適的理由:我們要開發現代範本庫,

要開發active library, 就必須動用範本程式設計技術, 要動用範本程式設計技術, 就必須利用語言的犄角旮旯, enable_if, type_traits, 甚至連早就古井無波的C宏也在亂世中重生, 看看boost::preprocessor有多詭異就知道了, 連C宏的圖靈完備性(預編譯期的)都被挖掘出來了。 為什麼要做這些?好玩?標榜?都不是, 開發庫的實際需求。 但這也正是最大的悲哀了。 在boost裡面因實際需求而動用語言細節最終居然能神奇的完成任務的最好教材就是boost::foreach, 這個小設施對語言細節的發掘達到了驚天地泣鬼神的地步, 不信你先試著自己去看看它的原始程式碼, 再看看作者介紹它的文章吧。 而boost::typeof也不甘其後——C++語言裡面有太多被“發現”而不是被“發明”的技術。 難道最初無意設置這些語言規則的傢伙們都是oracles?

因為沒有variadic templates,人們用巨集加上缺省範本參數來實現類似效果。因為沒有concepts,人們用範本加上析構函數的細節來完成類似工作。因為沒有typeof,人們用範本元程式設計和巨集加上無盡的細節來實現目標… C++開發者們的DIY精神不可謂不強。

然而,如果僅僅是因為要開發優秀的庫,那麼涉及這些細節都還是情有可原的,至少在C++09出現並且編譯器廠商跟上之前,這些都還能說是不得已而為之。但我們廣大的C++程式師呢?大眾是容易被誤導的,我也曾經是。以為掌握了更多的語言細節就更牛,但實際卻是那些語言細節十有八九是平時程式設計用都用不到的。C++中眾多的細節雖然在庫設計者手裡面有其用武之地,但普通程式師則根本無需過多關注,尤其是沒有實際動機的關注。一般性的編碼實踐準則,以及基本的程式設計能力和基本功,乃至基本的程式設計理論以及演算法設計。才是真正需要花時間掌握的東西。

學習最佳編碼實踐比學習C++更重要。看優秀的代碼也比埋頭用差勁的編碼方式寫垃圾代碼要有效。直接、清晰、明瞭、KISS地表達意圖比玩編碼花招要重要…

避免去過問任何語言細節,除非必要。這個必要是指在實際程式設計當中遇到問題,這樣就算需要過問細節,也是最省事的,懶惰者原則嘛。一個掌握了基本的程式設計理念並有較強學習能力的程式師在用一門陌生的語言程式設計時就算拿著那本語言的聖經從索引翻起也可以編出合格的程式來。十年學會程式設計不是指對每門語言都得十年,那一輩子才能學幾門語言哪,如果按字母順序學的話一輩子都別指望學到Ruby了;十年學習程式設計更不是指先把語言特性從粗到細全都吃透才敢下手程式設計,在實踐中提高才是最重要的。

至於這種摳語言細節的哲學為何能在社群裡面呈野火燎原之勢,就是一個心理學的問題了。想像人們在論壇上討論問題時,一個對語言把握很細緻的人肯定能夠得到更多的佩服,而由於論壇上的問題大多是小問題,所以解決實際問題的真正能力並不能得到顯現,也就是說,知識型的人能夠得到更多佩服,後者便成為動力和仿效的砝碼。然而真正的程式設計能力是與語言細節沒關係的,熟練運用一門語言能夠幫你最佳表達你的意圖,但熟練運用一門語言絕不意味著要把它的邊邊角角全都記住。懂得一些常識,有了程式設計的基本直覺,遇到一些細節錯誤的時候再去查書,是最節省時間的辦法。

書單

C++的書,Bjarne的聖經《The C++ Programming Language》是高屋建瓴的。《大規模C++程式設計》是挺務實的。《Accelerated C++》是最佳入門的。《C++ Templates》是僅作參考的。《C++ Template Metaprogramming》是精力過剩者可以玩一玩的,普通程式師碰都別碰的。《ISO.IEC C++ Standard 14882》不是拿來讀的。Bjarne最近在做C++的教育,新書是絕對可以期待的。

我是遑於給出一個類似《C++初學者必讀》這種書單的。C++的書不計其數,被公認的好書也不勝枚舉。只不過有些書容易給初學者造成一種錯覺,就是“學習C++就應該是這個樣子的”。比如有朋友提到的《高品質C/C++程式設計》,這本書有價值,但不適合初學者,初學者讀這樣的書容易一葉障目不見泰山。實際上,正確的態度是,細節是必要的。但細節是次要的。其實學習程式設計我覺得應該最先學習如何用虛擬碼表達思想呢,君不見《Introduction to Algorithm》裡面的代碼?《TAOCP》中的代碼?哦,對了它們是自己建立的語言,但這種僅教學目的的語言的目的就是為了避免讓寫程式的人一開始就忘了寫程式是為了完成功能,以為寫程式就是和語言細節作鬥爭了。Bjarne說程式的正確性最重要,boost的編碼標準裡面也將正確性列在性能前面。

一旦建立了正確的學習程式設計的理念,其實什麼書,只要是有點權威的都有些用處。都當成參考書,用的時候從目錄或索引翻,基本就對了。

倒底要不要學習C++

其實這個問題問得很沒有意義。“學C++”和“不學C++”這個二分法是沒意義的,為什麼?因為這個問題很表面,甚至很浮躁。重要的不是你掌握的語言,而是你掌握的能力,借用myan老大的話,“重要的是這個磨練過程,而不是結果,要的是你粗壯的腿,而不是你身上背的那袋鹽巴。”。此外學習C++的意義其實真的是醉翁之意不在酒,像C/C++這種系統級語言,在學習的過程中必須要涉及到一些底層知識,如記憶體管理、編譯連接系統、組合語言、硬體體系結構等等等等知識(注意,這不包括過分犄角旮旯的語言枝節)。這些東西也就是所謂的內功了(其實最最重要的內功還是長期學習所磨練出來的自學能力)。對此大嘴Joel在《Joel On Software》裡面提到的漏洞抽象定律闡述得就非常漂亮。

所以,答案是,讓你成為高手的並不是你掌握什麼語言,精通C++未必就能讓你成為高手,不精通C++也未必就能讓你成為低手。如果要抄起C++做一個項目的話會比大多數自認熟練C++的人要做得漂亮。所以關鍵的不是語言這個表層的東西,而是底下的本質矛盾。當然,不是說那就什麼語言都不要學了。C++是前者裡面最複雜的一種,支持最廣泛的程式設計範式。學語言是一個途徑,如果你把它用來磨練自己,可以。如果你把它用來作為學習系統底層知識的鑰匙,可以。如果你把它用來作為學習如何編寫優秀的代碼,如何組織大型的程式,如何進行抽象設計,可以。如果丟掉書本,光啃細節,我認為不可以。除非你必須要用到細節,像boost庫的coder們。

最後就以我在Bjarne的眾多訪談當中摘錄的一些關於如何學習C++的看法,只將其中我覺得最重要的幾段譯了一下,當然,其它也很重要。

翻譯成中文的意思是:我感覺人們過多關注了所謂“效率”以及跟隨程式設計風格的潮流,卻嚴重忽視了本不該被忽視的問題,如“我究竟想要構建什麼樣的系統”、“怎樣才能使它正確”。最關鍵的問題永遠是:“我究竟想要做什麼?”和“如何才能知道我的系統是否已經完成了呢?”就拿我來說吧,我會在編寫第一行代碼之前就考慮測試方案,而且這還是在我關於應當早於設計完成之前就進行編碼的觀點的前提之下。

誠然,C++非常複雜。誠然,人們迷失其中了。然而問題是,大多數人不是因為首先對自己想要表達什麼有了清晰的認識只不過在去C++語言中搜尋合適的語言特性時迷失的,相反,大多數人是在不覺成為語言律師的路上迷失在細節的叢林中的。事實是,只需對資料抽象、類體系結構(OOP)以及參數化類型(GP)有一個相當一般層面的瞭解,C++紛繁的語言特性也就清晰起來了。

因為沒有variadic templates,人們用巨集加上缺省範本參數來實現類似效果。因為沒有concepts,人們用範本加上析構函數的細節來完成類似工作。因為沒有typeof,人們用範本元程式設計和巨集加上無盡的細節來實現目標… C++開發者們的DIY精神不可謂不強。

然而,如果僅僅是因為要開發優秀的庫,那麼涉及這些細節都還是情有可原的,至少在C++09出現並且編譯器廠商跟上之前,這些都還能說是不得已而為之。但我們廣大的C++程式師呢?大眾是容易被誤導的,我也曾經是。以為掌握了更多的語言細節就更牛,但實際卻是那些語言細節十有八九是平時程式設計用都用不到的。C++中眾多的細節雖然在庫設計者手裡面有其用武之地,但普通程式師則根本無需過多關注,尤其是沒有實際動機的關注。一般性的編碼實踐準則,以及基本的程式設計能力和基本功,乃至基本的程式設計理論以及演算法設計。才是真正需要花時間掌握的東西。

學習最佳編碼實踐比學習C++更重要。看優秀的代碼也比埋頭用差勁的編碼方式寫垃圾代碼要有效。直接、清晰、明瞭、KISS地表達意圖比玩編碼花招要重要…

避免去過問任何語言細節,除非必要。這個必要是指在實際程式設計當中遇到問題,這樣就算需要過問細節,也是最省事的,懶惰者原則嘛。一個掌握了基本的程式設計理念並有較強學習能力的程式師在用一門陌生的語言程式設計時就算拿著那本語言的聖經從索引翻起也可以編出合格的程式來。十年學會程式設計不是指對每門語言都得十年,那一輩子才能學幾門語言哪,如果按字母順序學的話一輩子都別指望學到Ruby了;十年學習程式設計更不是指先把語言特性從粗到細全都吃透才敢下手程式設計,在實踐中提高才是最重要的。

至於這種摳語言細節的哲學為何能在社群裡面呈野火燎原之勢,就是一個心理學的問題了。想像人們在論壇上討論問題時,一個對語言把握很細緻的人肯定能夠得到更多的佩服,而由於論壇上的問題大多是小問題,所以解決實際問題的真正能力並不能得到顯現,也就是說,知識型的人能夠得到更多佩服,後者便成為動力和仿效的砝碼。然而真正的程式設計能力是與語言細節沒關係的,熟練運用一門語言能夠幫你最佳表達你的意圖,但熟練運用一門語言絕不意味著要把它的邊邊角角全都記住。懂得一些常識,有了程式設計的基本直覺,遇到一些細節錯誤的時候再去查書,是最節省時間的辦法。

書單

C++的書,Bjarne的聖經《The C++ Programming Language》是高屋建瓴的。《大規模C++程式設計》是挺務實的。《Accelerated C++》是最佳入門的。《C++ Templates》是僅作參考的。《C++ Template Metaprogramming》是精力過剩者可以玩一玩的,普通程式師碰都別碰的。《ISO.IEC C++ Standard 14882》不是拿來讀的。Bjarne最近在做C++的教育,新書是絕對可以期待的。

我是遑於給出一個類似《C++初學者必讀》這種書單的。C++的書不計其數,被公認的好書也不勝枚舉。只不過有些書容易給初學者造成一種錯覺,就是“學習C++就應該是這個樣子的”。比如有朋友提到的《高品質C/C++程式設計》,這本書有價值,但不適合初學者,初學者讀這樣的書容易一葉障目不見泰山。實際上,正確的態度是,細節是必要的。但細節是次要的。其實學習程式設計我覺得應該最先學習如何用虛擬碼表達思想呢,君不見《Introduction to Algorithm》裡面的代碼?《TAOCP》中的代碼?哦,對了它們是自己建立的語言,但這種僅教學目的的語言的目的就是為了避免讓寫程式的人一開始就忘了寫程式是為了完成功能,以為寫程式就是和語言細節作鬥爭了。Bjarne說程式的正確性最重要,boost的編碼標準裡面也將正確性列在性能前面。

一旦建立了正確的學習程式設計的理念,其實什麼書,只要是有點權威的都有些用處。都當成參考書,用的時候從目錄或索引翻,基本就對了。

倒底要不要學習C++

其實這個問題問得很沒有意義。“學C++”和“不學C++”這個二分法是沒意義的,為什麼?因為這個問題很表面,甚至很浮躁。重要的不是你掌握的語言,而是你掌握的能力,借用myan老大的話,“重要的是這個磨練過程,而不是結果,要的是你粗壯的腿,而不是你身上背的那袋鹽巴。”。此外學習C++的意義其實真的是醉翁之意不在酒,像C/C++這種系統級語言,在學習的過程中必須要涉及到一些底層知識,如記憶體管理、編譯連接系統、組合語言、硬體體系結構等等等等知識(注意,這不包括過分犄角旮旯的語言枝節)。這些東西也就是所謂的內功了(其實最最重要的內功還是長期學習所磨練出來的自學能力)。對此大嘴Joel在《Joel On Software》裡面提到的漏洞抽象定律闡述得就非常漂亮。

所以,答案是,讓你成為高手的並不是你掌握什麼語言,精通C++未必就能讓你成為高手,不精通C++也未必就能讓你成為低手。如果要抄起C++做一個項目的話會比大多數自認熟練C++的人要做得漂亮。所以關鍵的不是語言這個表層的東西,而是底下的本質矛盾。當然,不是說那就什麼語言都不要學了。C++是前者裡面最複雜的一種,支持最廣泛的程式設計範式。學語言是一個途徑,如果你把它用來磨練自己,可以。如果你把它用來作為學習系統底層知識的鑰匙,可以。如果你把它用來作為學習如何編寫優秀的代碼,如何組織大型的程式,如何進行抽象設計,可以。如果丟掉書本,光啃細節,我認為不可以。除非你必須要用到細節,像boost庫的coder們。

最後就以我在Bjarne的眾多訪談當中摘錄的一些關於如何學習C++的看法,只將其中我覺得最重要的幾段譯了一下,當然,其它也很重要。

翻譯成中文的意思是:我感覺人們過多關注了所謂“效率”以及跟隨程式設計風格的潮流,卻嚴重忽視了本不該被忽視的問題,如“我究竟想要構建什麼樣的系統”、“怎樣才能使它正確”。最關鍵的問題永遠是:“我究竟想要做什麼?”和“如何才能知道我的系統是否已經完成了呢?”就拿我來說吧,我會在編寫第一行代碼之前就考慮測試方案,而且這還是在我關於應當早於設計完成之前就進行編碼的觀點的前提之下。

誠然,C++非常複雜。誠然,人們迷失其中了。然而問題是,大多數人不是因為首先對自己想要表達什麼有了清晰的認識只不過在去C++語言中搜尋合適的語言特性時迷失的,相反,大多數人是在不覺成為語言律師的路上迷失在細節的叢林中的。事實是,只需對資料抽象、類體系結構(OOP)以及參數化類型(GP)有一個相當一般層面的瞭解,C++紛繁的語言特性也就清晰起來了。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示