0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

學(xué)習(xí)C++(以及編程)的原因及方法詳讀

C語言專家集中營 ? 2017-11-24 16:58 ? 次閱讀

我的blog以前很長一段時間關(guān)注的都是C++中的技術(shù)&細節(jié),乃至于讀者和應(yīng)者都寥寥。然而5月份的時候?qū)懙囊黄澳銘?yīng)當(dāng)如何學(xué)習(xí)C++”,閱讀量卻達到了3萬多,在blog上所有文章中卻是最高的(且遠遠超過了第二位);評論數(shù)目也有一百多。為什么獨獨這篇能夠激起這么多的回應(yīng),想必是國內(nèi)的C++社群被C++壓抑太久,或者,嚴(yán)格來說,是被C++的教育方式壓抑太久。實際上,不管是在各大國內(nèi)論壇上,還是在comp.lang.c++.moderated這樣的國際C++論壇上,乃至于在douban上的小組內(nèi),有心者都會發(fā)現(xiàn),對C++語言的細節(jié)的關(guān)注一直都沒有停止過,同樣,對C++語言的細節(jié)的抱怨也從來都沒有停止過。一個例子就是comp.lang.c++.moderated上的一個技術(shù)牛人James Kanze說的,他說接觸C++十年了,到現(xiàn)在還需要不時去翻C++標(biāo)準(zhǔn)。這就難怪Eric Raymond老大在《The Art of Unix Programming》中說“C++是反緊湊”的了。C++中的細節(jié)太多,就算都看過了,也不可能都記住。更關(guān)鍵的是,就算都記住了,也不能讓你成為一個真正的好程序員。

絕大多數(shù)人都把細節(jié)太多(或者用貶義詞來說就是“陰暗角落太多”)歸結(jié)為C++的本質(zhì)問題,認(rèn)為一切邪惡由此而生。也正因此,大約9月份的時候,Linus在郵件列表上說“C++是一門有思想包袱的語言;僅僅是為了讓程序員遠離C++,我也要用C”。這句短短的話在國內(nèi)引起了很大的反應(yīng),最初是劉江轉(zhuǎn)了Linus的話,然后云風(fēng)和孟巖都發(fā)表了自己的看法;我也寫了一篇“Why C++”(后來發(fā)給Bjarne,Bjarne對這篇文章做了一個友情評注)。

然而,這一通渾水?dāng)囘^之后,我相信引起的變化未必很大。大多數(shù)原先的反對者能從中找出反對的理由,于是更加反對;大多數(shù)原先的贊同者也能從中找到贊同的理由,于是更加贊同;而剩下來的原先沒有明確意見的,看雙方各有各的道理,可能還是沒有頭緒。

擺脫自我服務(wù)偏見——理性思考的前提

《決策與判斷》上提到過一個有趣的真實故事:1980年的某一天,美國空戰(zhàn)司令部的計算機突然發(fā)出警報——蘇聯(lián)的一枚核彈正在向美國本土飛來。司令部立即調(diào)兵遣將,迅速為一場核戰(zhàn)做好了準(zhǔn)備,然而3分鐘之后,工程人員發(fā)現(xiàn)是計算機的一個小零部件故障造成的。然而,這場虛驚之后,大眾的反應(yīng)才是真正有意思的:原先支持核武裝的,認(rèn)為現(xiàn)在感覺更加安全了(因為“事實證明這類的故障是完全可克服的”);而原先反對核武裝的則認(rèn)為更不安全了(因為“這類錯誤信號可能導(dǎo)致蘇聯(lián)過度反應(yīng),引發(fā)真正的核戰(zhàn)”)。類似的情況也發(fā)生在三里島核泄露事件之后,同樣的,反對者認(rèn)為(“這表明管理部門沒有辦法安全管理核能”),支持者認(rèn)為(“這正表明這樣的危險沒有想像得那么嚴(yán)重,是可克服的”)。社會心理學(xué)把諸如此類的現(xiàn)象總結(jié)為“自我服務(wù)偏見”。不幸的是,“真理越辯越明”其實只適用于理性思考者。

為什么啰嗦這么一大通呢?就是因為,一直以來泛濫于程序員社群的“語言之爭”,背后真正的原因其實并不在于語言實質(zhì)上的優(yōu)劣,而在于觀察者的眼睛。在觀察者的眼睛里面,語言并非一門工具,而是自己花了N多時間(其中尤數(shù)C++為最)來“修煉”的技能,對于這樣的技能,被否定無疑等同于自己被否定。所以,從心理學(xué)上講,語言并不是工具(盡管一直有這么一種呼吁),而是信仰。這樣的信仰在越是花得時間久的語言上越是激烈。有趣的是,幾乎所有的“熱鬧”的社群都有這樣的現(xiàn)象,Java、Python、Ruby…莫不如是;因為就算語言本身不復(fù)雜,程序員仍然還是要投入大量的精力去學(xué)習(xí)各種各樣的框架類庫(想想Java的那些框架?)。因此這些語言社區(qū)的信仰未必不比C++社群的強烈。

然而,一旦弄清我們?yōu)槭裁磿颜Z言當(dāng)成信仰,就非常有助于擺脫在看待語言時的“自我服務(wù)偏見”,從客觀的角度去看待問題?!爱?dāng)你看到的是支持某個意見的證據(jù)時,試著去想一想有哪些證據(jù)是不支持它的”。

那么為什么要擺脫自我服務(wù)偏見?說小了,是為了成為一個更優(yōu)秀的程序員(誰也不希望因為偏見而去使用一門低效的語言乃至不妥當(dāng)?shù)恼Z言)。說大了是節(jié)省生命(因為偏見可能導(dǎo)致越陷越深,浪費時間)。

所以,如果你能夠理性的思考我們將要討論的問題,避免自我服務(wù)偏見(就當(dāng)你從來沒有花時間在C++上一樣)。那么我們便可以開始討論真正的問題了。

現(xiàn)在,幾乎每個學(xué)習(xí)C++的都知道C++的核心問題是其復(fù)雜性;甚至本身不在C++社群的,也知道這是事實。群眾的眼睛是雪亮的,何況這還是個太顯而易見的事實。

但看了無數(shù)篇闡述C++復(fù)雜性的文章,和爭論C++復(fù)雜性的吐沫星子(包括我前段時間寫的兩篇關(guān)于C++的總結(jié))。我始終都有一個感覺——沒分析透,就跟盲人摸象一樣。正如“Why C++”的一位讀者批評的,我在文章里面沒有寫明到底哪些是C++的“非本質(zhì)復(fù)雜性”。當(dāng)然,我自己憑感覺就能知道,而接觸C++一段時間的人大致也能知道,但新手乃至非新手則對我所謂的“非本質(zhì)復(fù)雜性”根本沒有一個具體的認(rèn)識,這就使得那篇“Why C++”脫離了原本的意圖——面向所有C++使用者和學(xué)習(xí)者。

同樣的原因,在寫了“你應(yīng)當(dāng)如何學(xué)習(xí)C++”一文之后,當(dāng)孟巖先生邀請我給《程序員》寫一個系列的文章,介紹一下我在接觸C++的過程中的態(tài)度和認(rèn)識轉(zhuǎn)變時,我雖然非常高興的答應(yīng)了,但直到現(xiàn)在3個月過去了還是顆粒無收。為什么?因為我覺得真正本質(zhì)的問題沒有被清晰的觸摸到;所以直到現(xiàn)在我都沒有動筆,免得廢話說了一大堆,除了能被當(dāng)成小說讀讀之外,對真正考慮是否要學(xué)習(xí)乃至使用C++的人未必有什么實際用處。

然而,這么個念頭一直都放在潛意識里面。前一陣子和Bjarne通信,談到了關(guān)于C++復(fù)雜性的一些想法,在郵件里面總結(jié)了一下C++的復(fù)雜性來源,感覺思路清晰了許多。而這篇文章要達到的目的,正是傳達對C++的復(fù)雜性的一個具體而明確的認(rèn)識,有了這個認(rèn)識作為支持,我們便可以推導(dǎo)出學(xué)習(xí)C++的最佳(實踐者)的方法。

為什么要學(xué)習(xí)(并使用)C++

顯然,如果找不出要學(xué)習(xí)C++的理由,那么談什么“正確的學(xué)習(xí)方法”等于是廢話。

首先重復(fù)一句Bjarne的話:“我們的系統(tǒng)已經(jīng)是極度復(fù)雜的了,為了避開C++的復(fù)雜性而干脆不用C++(Linus的做法),無異于因噎廢食。”在所有可用C和C++的領(lǐng)域,C++都是比C更好的語言。當(dāng)我說“更好的”時候,我說的是C++擁有比C更安全的類型檢查、更好的抽象機制、更優(yōu)秀的庫。當(dāng)然,凡事都有例外,如果你做的項目1)不大。2)編碼中用不到什么抽象機制,甚至ADT(抽象數(shù)據(jù)類型,例如std::complex這種不含多態(tài)和繼承的)也用不到,RAII也用不到,異常也用不到。3)你連基礎(chǔ)庫(如,簡化資源管理的智能指針、智能容器)都用不著。那么也許你用C的確沒問題;所以如果你的情況如此,不用和我爭論,因為我無法反駁你。我們這里說的領(lǐng)域大致是Bjarne在“C++應(yīng)用列表”里面列出來的那些地方。

底線是:如果把C++中的諸多不必要的復(fù)雜性去掉,留下那些本質(zhì)的,重要的語言特性,簡化語言模型,消除歷史包袱。即便是C++的反對者也許也很難找到理由說“我還是不用C++”。在我看來,一個真正從實踐意義上理性反對使用C++的人只有一個理由:C++的復(fù)雜性帶來的混亂抵消乃至超過了C++的抽象機制和庫(在他的特定項目中)帶來的好處。

值得注意的是,這里需要避免一個陷阱,就是一旦人們認(rèn)定了“C++不好”,那么這個理由就會“長出自己的腳來”,即,就算我們拿掉C++的復(fù)雜性,他們可能也會堅持還是不用C++,并為之找一堆理由。我假定你不是這樣的人。不過,也許最可能的是他會說:“問題是我們今天用的C++并非如此(簡潔),你的假設(shè)不成立。”是的,我的假設(shè)不成立。但雖然我們無法消除復(fù)雜性,我們實際上是可以容易地避開復(fù)雜性,避短揚長的。這也是本文的要點,容我后面再詳述。

當(dāng)然,到現(xiàn)在你可能還是會說。我還是不用C++,因為我可以用D;或者如果你本來做的項目就不需要C++,你則可能會說,我用Python。首先,如果你的項目能用Java/Python乃至Ruby做,那么用C++是自討苦吃。因為能用那些語言代表你的項目在效率上本身要求就不高,那么用一門效率上討不到太大好處,復(fù)雜性上卻綽綽有余的語言,有什么價值呢?其次,如果你的項目效率是很重要的,你可能會說可以用D。然而現(xiàn)實是D在工業(yè)界尤其是國內(nèi)被運用得非常少,幾乎沒有。而C++卻有大量的既有代碼,已經(jīng)使用C++去做他們的產(chǎn)品公司,在很長一段時間之內(nèi)幾乎是不可能用別的語言重寫代碼的,正如Joel所說,決定重寫一個非平凡的代碼基==自殺。所以,我們至少要注意以下兩個明顯的事實:

事實1:C++在工業(yè)界仍有穩(wěn)定的核心市場。

這個事實大概不需要多加闡述,很多大公司的核心技術(shù)還是要靠C++來支撐的(見Bjarne主頁上的C++應(yīng)用列表)。所謂事實,就是未必是大家最愿意承認(rèn)的情況,但又不得不承認(rèn)。C++積累了龐大的代碼基,這個代碼基不是一朝一夕能夠推翻的。D從語言角度來說的確優(yōu)于C++,但最關(guān)鍵的就是還沒有深入工業(yè)界(也許根本原因是沒有錢支持,但這不是我們討論的重點)。而C呢,根據(jù)Bjarne本人的說法,他的觀察是主流工業(yè)界的趨勢一直是“從C到C++”的,而不是反過來,至少在歐美是如此。在國內(nèi)我們則可以通過CSDN上的招聘情況得到一個大致類似的信息。

事實2:C++程序員往往能享受到有競爭力的薪酬。

是的,這不是一篇不食人間煙火的技術(shù)文章。這個事實基于的邏輯很簡單:物以稀為貴。Andrei Alexandrescu這次來中國SD2.0大會的時候,在接受采訪時也說過:“最賺錢的軟件(如MS Office)是C++寫的”。孟巖也在blog上提到這么個事實,我想他作為CSDN的技術(shù)總編,業(yè)界觀察肯定比我清晰深刻。所以我這里就不多廢話了。

當(dāng)然,以上邏輯并不就意味著在慫恿你去學(xué)C++,一切還要看你的興趣。所以如果你志不在C++身處的那些應(yīng)用領(lǐng)域,那這篇文章并非為你而寫。

“C++的復(fù)雜性是根本原因”——一個有漏洞的推理

一旦我們認(rèn)識了C++在一些領(lǐng)域是有需求的(值得學(xué)習(xí)和掌握的)這個問題之后,就可以接下來討論“怎樣正確學(xué)習(xí)和掌握C++”這個核心問題了。

其實,對于這個問題,Bjarne已經(jīng)宣傳了十年。早在99年的時候Bjarne就寫了“Learning C++ as A New Language”,并在好幾篇技術(shù)訪談(這里,這里,這里,還有這里)里面提到如何正確對待和使用C++中支持的多種抽象機制的問題。Andrew Koenig也寫了一本現(xiàn)代C++教程Accelerated C++》(這本書后面還會提到)。然而這么多年來,C++社群的狀況改善了嗎?就我所知,就算有改善,也是很小的。學(xué)習(xí)者還是盲目鉆語言細節(jié),只見樹木不見森林;網(wǎng)上還是彌漫著各種各樣的“技術(shù)”文章和不靠譜的“學(xué)習(xí)C++的XX個建議”;一些業(yè)界的有身份的專家還是在一本接一本的出語言孔乙己的書(寫一些普通程序員八輩子用不著的技巧和碰不著的角落);而業(yè)界真正使用C++的公司在面試的時候還總是問一些邊邊角角的細節(jié)問題,而不是考察編程的基本素養(yǎng)(不,掌握所有的語言細節(jié)也不能讓你成為一個合格的程序員)。這個面試?yán)砟钍清e誤的,估計其背后的推理應(yīng)該是“如果這個家伙不知道這個細節(jié),那么估計他對語言也熟悉不到哪兒去;而如果他知道,那么雖然他可能并不是好的程序員,但我們還是能夠就后一個問題進一步測試的”,這個理念的問題在于,對語言熟悉到一定程度(什么程度后面會具體建議)就已經(jīng)可以很好的編程了(剩下的只需查查文檔);而很多公司在測試“對語言熟悉程度”的時候走得明顯太遠了(比如,問臨時對象生命期和析構(gòu)順序當(dāng)然是無可厚非的,但問如何避免一個類被拷貝或者如何避免其構(gòu)建在堆上?);當(dāng)然,有些語言知識是必須要提前掌握的,具體有哪些后面會提到,面試的時候并非不能問語言細節(jié),關(guān)鍵是“問哪些”。

所以說:

事實3:C++的整個生態(tài)圈這么些年來在學(xué)習(xí)C++的哲學(xué)上,實在沒有多少改善。

為什么?是因為Bjarne介紹的學(xué)習(xí)方法在技術(shù)上沒有說到點子上?是Andrew Koenig的書寫得不夠好?說了誰也不會相信。因為實際上,這里的原因根本不是技術(shù)上的,而是非技術(shù)的。

眾所周知的一個事實是,從最表層講,C++的最嚴(yán)重問題是在語言學(xué)習(xí)階段占用了學(xué)習(xí)者的太多時間。翻一翻你的C++書架或者電子書目錄,絕大多數(shù)的C++“經(jīng)典”都是在講語言。在我們通常的意義上,要“入門”C++,在語言上需要耗的時間一般要兩三年。而要“精通”C++,則搞不好需要耗上十年八年的。(這跟Peter Norvig說的“十年學(xué)習(xí)編程”其實不是一回事,人家那是說一般意義上的編程技能,不是叫你當(dāng)語言律師。)

那為什么我說“C++的復(fù)雜性是根本原因”是個有漏洞的推理呢?因為,要讓人們在使用一門語言去做事情之前耗上大量時間去學(xué)習(xí)語言中各種復(fù)雜性,除了語言本身的復(fù)雜性的事實之外,還有一個重要的事實,那就是學(xué)習(xí)者的態(tài)度和(更重要的)方法。而目前大多數(shù)C++學(xué)習(xí)者的態(tài)度和方法是什么呢?——在真正用C++之前看上一摞語言書(日常編程八輩子都未必用得到)。而為什么會存在這樣的學(xué)習(xí)態(tài)度呢?這就是真正需要解釋的問題。實際上,有兩方面的原因:

事實4:市面上的絕大多數(shù)C++書籍(包括很多被人們廣泛稱為“必讀經(jīng)典”的)實際上都是反面教材。

也就是說,隨便你拿起哪本C++書籍(包括很多被人們廣泛稱為“必讀經(jīng)典”的),那么有很大的可能這本書中的內(nèi)容不是你應(yīng)該學(xué)的,而是你不應(yīng)該學(xué)的。我之所以這么說有兩個原因,因為一,我曾經(jīng)是受害者。二,也是更實質(zhì)性的原因,這些所謂的必讀經(jīng)典,充斥的是介紹C++中的陷阱和對于C++的缺陷的各種workarounds(好聽一點叫Idioms(慣用法)或techniques(技術(shù)));又因為C++中的這類陷阱和缺陷實在數(shù)不勝數(shù),所以就拉出了一個“長尾”;這類書籍在所有語言中都存在(“C缺陷和陷阱”、“Effective Java”、“Effective C#”等等),然而在C++里面這個尾巴特別長,導(dǎo)致這類書數(shù)不勝數(shù)。三,這些書中列出來的缺陷和陷阱根本不區(qū)分常見程度,對于一個用本程序員來說,應(yīng)該希望看到“從最常見的問題到最不常見的問題”這樣的順序來羅列內(nèi)容,然而這些書里面要么全部混在一起,要么按照“資源管理、類設(shè)計、泛型”這樣的技術(shù)分類來介紹內(nèi)容,這根本毫無幫助(如果我看到一個章節(jié)的內(nèi)容,我當(dāng)然知道它講的是類設(shè)計還是資源管理,還用廢話么?),使得一個學(xué)習(xí)者無法辨別并將最重要的時間花在最常見的問題之上。

最最關(guān)鍵的是:這些書當(dāng)中介紹的內(nèi)容與成為一個好程序員根本毫無關(guān)系,它們頂多只能告訴你——嗨,小心跌入這個陷阱。或者告訴你——嗨,你知道當(dāng)你(八輩子都不一定遇到)遇到這個需求的時候,可以通過這個技巧來得以解決嗎?結(jié)果讀了一本又一本之后,你腦袋里除了塞滿了“禁止”、“警戒”、“燈泡”符號之外,真正的編程素質(zhì)卻是一無長進。又或者有這樣一類書,熱衷于解釋語言實現(xiàn)背后的機制,然而語言特性本質(zhì)上是干嘛用的?是用來在實際編碼中進行抽象的(說得好聽一點就是“設(shè)計”),不是用來告訴你這個特性是怎么支持的。比如我就見過以下的情景:面試官問:“你知道虛函數(shù)嗎?”得到的回答是一堆關(guān)于虛函數(shù)表機制的解釋。面試官又問:“那虛函數(shù)的好處是什么呢?”到底為什么要虛函數(shù)呢?得到的回答是:“恩…啊…就是…多態(tài)吧”(這時已經(jīng)覺得回答不夠深刻了)。再問:“那多態(tài)是干嘛的呢?”啞口無言。

事實5:就算記住一門語言的所有細節(jié)也不能讓你成為一個合格的程序員。

事實6:了解語言實現(xiàn)固然有其實踐意義(在極端場合的hack手法,以及出現(xiàn)底層bug的時候迅速定位問題),然而如果為了了解語言機制而去了解語言機制便脫離了學(xué)習(xí)語言的本意了。

在C++里面這樣的情況很多見:知道了語言實現(xiàn)的底層機制,卻不知道語言特性本身的意義在什么地方。本末倒置。為什么?書害的。二,這類書當(dāng)中介紹的所有情景加起來其實只屬于那20%(二八法則),甚至20%都不到的場景(究竟是哪些書,后面會介紹,我不便直接列出書名,打擊面太大,但我會把我認(rèn)為essential的書列出來)。這就是為什么我說“八輩子都用不著”的原因。

事實7:80%的C++書籍(包括一些“經(jīng)典”)只涉及到20%(或者更少)的場景。

你可能會說,那難道這些書就根本不值得看了嗎?

我的回答是,對。根本不值得看?!侵档梅旁谂赃呑鳛楸匾臅r候的參考(記住從索引或目錄翻起,只看嚴(yán)格必要的部分),如果你是個嚴(yán)肅的程序員的話。因為不管承認(rèn)與否,墨菲法則的強大力量是不可忽視的——如果有一個可能遇到的陷阱,那么總會遇到的。而同樣,C++的那些奇技淫巧也并非空穴來風(fēng),總有時候會需要用到的。但是你不需要預(yù)先把C++的所有細節(jié)和技巧存在腦子里才能夠去編程,即:

建議1:有辨別力地閱讀(包括那些被廣泛稱為“經(jīng)典”的)C++書籍。

如果書中介紹的某塊內(nèi)容你認(rèn)為在日常編程中基本不會用到(屬于20%場景),那么也許最好的做法是非常大概的瀏覽一下,留個印象,而不是順著這條線深究下去。關(guān)于在初學(xué)的時候應(yīng)該讀哪些書,后面還會提到。

實際上,除了語言無關(guān)的編程修養(yǎng)之外(需要閱讀什么書后面會提到),對于C++這門特定的語言,要開始用它來編程,你只需知道一些基礎(chǔ)但重要的語言知識(需要閱讀哪些書后面會提到)以及“C++里面有許多缺陷和陷阱”的事實,并且——

建議2:養(yǎng)成隨時查閱資料和文檔的習(xí)慣。

“查文檔”幾乎可以說是作為一個程序員最重要的能力(是的,能力)了;它是如此重要,以至于在英文里面有一個專門的縮寫——RTFM。為什么這個能力如此重要,原因很簡單:編程領(lǐng)域的知識太雞零狗碎了。不僅知識量巨大,而且知識的細節(jié)性簡直是任何學(xué)科都無與倫比的(隨便找一個框架類庫看看它的API文檔吧)。所以,把如此巨量的信息預(yù)先放在腦子里不僅不實際,而且簡直是自作孽。你需要的是“元能力”,也就是查文檔的能力——從你手頭遇到的問題開始,進行正確合理的分析,預(yù)測問題的解決方案可能在什么地方,找到關(guān)于后者的資料,閱讀理解,運用。

同樣,在C++中也是如此,如果你從學(xué)習(xí)C++一開始就抱著這種態(tài)度的話,那么即便等到面試的時候被問到某個語言細節(jié),你也可以胸有成竹的說你雖然并不知道這個細節(jié),但在實際編碼中遇到相應(yīng)問題的時候肯定會找到合適的參考資料并很快解決問題(解決問題,才是最終目的)。當(dāng)然,更大的可能性是,你在平常編碼中已經(jīng)接觸過了最常見的那80%的陷阱和技巧了,由于你用的是實踐指導(dǎo)性的學(xué)習(xí)方式,所以你遇到的需要去學(xué)習(xí)的陷阱和技巧幾乎肯定都是常見場景下的,比沒頭蒼蠅似的逮住一本C++“經(jīng)典”就“細細研讀”的辦法要高效N倍,因為在沒有實踐經(jīng)驗的情況下,你很可能會認(rèn)為其中的每個技巧,每個陷阱,都是同樣概率發(fā)作的。

為什么市面上的C++書熱衷于那些細節(jié)和技巧呢?

你用一個天生用來開啤酒瓶的工具開了啤酒瓶,不但啥成就感也沒有,而且誰也不會覺得你牛13。然而,如果你發(fā)明了一種用兩根筷子也能打開啤酒瓶的辦法,或者你干脆生就一口好牙可以把瓶蓋啃開,那也許就大不一樣了。人家就會覺得你很好很強大。

事實8:每個人都喜歡戴著腳鐐跳舞。

也就是說,如果你用一個天生為某個目的的工具來做他該做的事情,沒有人會喝彩,你也不會覺得了不起。但如果你用兩個本身不是為某個目的的工具組合出新功能的話,你就是“創(chuàng)新”者(盡管也許本來就有某個現(xiàn)成的工具可用)。

而C++則是這些“創(chuàng)新”的土壤,是的,我說的就是無窮無盡的workarounds和慣用法。但問題是,這些“創(chuàng)新”其實根本不是創(chuàng)新,你必須認(rèn)識到的是,他們都只不過是在沒有first-class解決方案的前提下不得已折騰出來的替補方案。是的,它們某種程度上的確可以叫創(chuàng)新,甚至研究可行的解決方案本身也是一件非常有意思的事情,但——

事實9:我知道它們很有趣,但實際上它們只是補丁方案。

是的,不要因為這些“創(chuàng)新”方案有趣就忍不住一頭鉆進去。你之所以覺得有趣是因為當(dāng)你一定程度上熟悉了C++之后,C++的所有一切,包括缺陷,對你來說就成了一個“既定事實”,一個背景,一個習(xí)以為常的東西(人是有很強的適應(yīng)性的)。因此,當(dāng)你發(fā)現(xiàn)在這個習(xí)以為常的環(huán)境下居然出現(xiàn)了新的可能性時,你當(dāng)然是會歡呼雀躍的(比如我當(dāng)年讀《Modern C++ Design》的時候就有一次從早讀到晚,午飯都沒吃),然而實際上呢?其它語言中也許早就有first-class的支持了,其它語言也許根本不需要這個慣用法,因為它們就沒有這些缺陷。此外,從實踐的角度來說,更重要的是,這些“解決方案”也許你平時編程根本就用不到。

不,我當(dāng)然不是說這些補丁方案不重要。正如前面所說,C++中繁雜的技巧并非空穴來風(fēng),總有實際問題在背后驅(qū)動的。但問題是,對于我們?nèi)粘>幊虂碚f,這些“實際問題”簡直是八桿子打不著的。犯不著先費上80%的勁兒把20%時候才用到的東西揣在腦子里,用的時候查文檔或書就行了。

看到這里,塑造C++中特定的心態(tài)哲學(xué)的另一個原因想必你也已經(jīng)知道了。實際上,這個原因才是真正根本的。前面說的一個原因是C++書籍市場(教育)造就的,然而為什么人們喜歡寫這些書呢?進一步說,為什么人們喜歡讀這些書呢?(我承認(rèn),我也曾經(jīng)讀得津津有味。)答案很簡單:心理。每個人都喜歡戴著腳鐐跳舞(事實8)。認(rèn)識到這一點不是為了提倡它,而是只有當(dāng)我們認(rèn)識到自己為什么會津津有味地去鉆研一堆補丁解決方案的時候,我們才真正能夠擺脫它們的吸引。

總而言之,C++的復(fù)雜性只是一個必要條件,并非問題的根本癥結(jié)。根本癥結(jié)在于人的心理,每個人都喜歡戴著腳鐐跳舞,并且以為是“創(chuàng)新”。意識到這一點之后可以幫我們避免被各種各樣名目繁多的語言細節(jié)和技巧占去不必要的時間。

然而,C++的復(fù)雜性始終是一個不可回避的現(xiàn)實。C++中有大量的陷阱和缺陷,后者導(dǎo)致了數(shù)目驚人的慣用法和workarounds。不加選擇的全盤預(yù)先學(xué)習(xí),是非常糟糕的做法,不僅低效,而且根本沒有必要,實在是浪費生命。愛因斯坦曾經(jīng)說過,“我只想知道‘他’(宇宙)的設(shè)計理念,其它的都是細節(jié)”。然而,正如另一些讀者指出的,如果對C++中的這些細節(jié)事先一點都沒有概念的話,那么實際編碼中一旦遇到恐怕就變成沒頭蒼蠅了,也許到哪里去RTFM都不知道。這也是為什么那么多C++面試都會不厭其煩地問一些有代表性的語言細節(jié)的原因。

把細節(jié)全盤裝在腦子里固然不好,但對細節(jié)一無所知同樣也不是個辦法。那么對于C++程序員來說,在學(xué)習(xí)中究竟應(yīng)該以怎樣的態(tài)度和學(xué)習(xí)方法來對付C++的復(fù)雜性呢?其實答案也非常簡單,首先有一些很重要&必須的語言細節(jié)&特性是需要掌握的,然后我們只需知道在C++中大抵有哪些地方有復(fù)雜性(陷阱、缺陷),那么遇到問題的時候自然能夠知道到哪兒去尋找答案了。具體的建議在后文。

C++的復(fù)雜性分類

本來這一節(jié)是打算做成一個C++復(fù)雜性索引的,然而一來C++的復(fù)雜性太多,二來網(wǎng)上其實已經(jīng)有許多資料(比如Bjarne Stroustrup本人的C++ Technical FAQ就是一個很好的文檔),加上市面上的大多數(shù)C++書里面也不停的講語言細節(jié);因此實際上我們不是缺乏資料,而是缺乏一種索引這些資料的辦法,以及一種掌控這些復(fù)雜性的模塊化思維方法。

由于以上原因,這里并不詳細羅列C++的復(fù)雜性,而是提供一個分類標(biāo)準(zhǔn)。

C++的復(fù)雜性有兩種分類辦法,一是分為非本質(zhì)復(fù)雜性和本質(zhì)復(fù)雜性;其中非本質(zhì)復(fù)雜性分為缺陷和陷阱兩類。另一種分類辦法是按照場景分類:庫開發(fā)場景下的復(fù)雜性和日常編碼的復(fù)雜性。從從事日常編碼的實踐者的角度來說,采用后一種分類可以讓我們迅速掌握80%場景下的復(fù)雜性。

二八法則

以下通過列舉一些常見的例子來解釋這種分類標(biāo)準(zhǔn):

80%場景下的復(fù)雜性:

1. 資源管理(C++日常復(fù)雜性的最主要來源):深拷貝&淺拷貝;類的四個特殊成員函數(shù);使用STL;RAII慣用法;智能指針等等。

2. 對象生命期:局部&全局對象生存期;臨時對象銷毀;對象構(gòu)造&析構(gòu)順序等等。

3. 多態(tài)

4. 重載決議

5. 異常(除非你不用異常):棧開解(stack-unwinding)的過程;什么時候拋出異常;在什么抽象層面上拋出異常等等。

6. undefined&unspecified&implementation defined三種行為的區(qū)別:i++ + ++i是undefined behavior(未定義行為——即“有問題的,壞的行為,理論上什么事情都可能發(fā)生”);參數(shù)的求值順序是unspecified(未指定的——即“你不能依賴某個特定順序,但其行為是良好定義的”);當(dāng)一個double轉(zhuǎn)換至一個float時,如果double變量的值不能精確表達在一個float中,那么選取下一個接近的離散值還是上一個接近的離散值是implementation defined(實現(xiàn)定義的——即“你可以在實現(xiàn)商的編譯器文檔中找到說明”)。這些問題會影響到你編寫可移植的代碼。

(注:以上只是一個不完全列表,用于演示該分類標(biāo)準(zhǔn)的意義——實際上,如果我們只考慮“80%場景下的復(fù)雜性”,記憶和學(xué)習(xí)的負(fù)擔(dān)便會大大減小。)

20%場景下的復(fù)雜性:

1. 對象內(nèi)存布局

2. 模板:偏特化;非類型模板參數(shù);模板參數(shù)推導(dǎo)規(guī)則;實例化;二段式名字查找;元編程等等。

3. 名字查找&綁定規(guī)則

4. 各種缺陷以及缺陷衍生的workarounds(C++書中把這些叫做“技術(shù)”):不支持concepts(boost.concept_check庫);類型透明的typedef(true-typedef慣用法);弱類型的枚舉(強枚舉慣用法);隱式bool轉(zhuǎn)換(safe-bool慣用法);自定義類型不支持初始化列表(boost.assign庫);孱弱的元編程支持(type-traits慣用法;tag-dispatch慣用法;boost.enable_if庫;boost.static_assert庫);右值缺陷(loki.mojo庫);不支持可變數(shù)目的模板參數(shù)列表(type-list慣用法);不支持native的alignment指定。

(注:以上只是一個不完全列表。你會發(fā)現(xiàn),這些細節(jié)或技術(shù)在日常編程中極少用到,尤其是各種語言缺陷衍生出來的workarounds,構(gòu)成了一個巨大的長尾,在無論是C++的書還是文獻中都占有了很大的比重,作者們稱它們?yōu)榧夹g(shù),然而實際上這些“技術(shù)”絕大多數(shù)只在庫開發(fā)當(dāng)中需要用到。)

非本質(zhì)復(fù)雜性&本質(zhì)復(fù)雜性

此外,考慮另一種分類辦法也是有幫助的,即分為非本質(zhì)復(fù)雜性和本質(zhì)復(fù)雜性。

非本質(zhì)復(fù)雜性(不完全列表)

1. 缺陷(指能夠克服的問題,但解決方案很笨拙;C++的書里面把克服缺陷的workarounds稱作技術(shù),我覺得非常誤導(dǎo)):例子在前面已經(jīng)列了一堆了。

2. 陷阱(指無法克服的問題,只能小心繞過;如果跌進去,那就意味著你不知道這個陷阱,那么很大可能性你也不知道從哪去解決這個問題):一般來說,作為一個合格的程序員(不管是不是C++程序員),80%場景下的語言陷阱是需要記住才行的。比如深拷貝&淺拷貝;基類的析構(gòu)函數(shù)應(yīng)當(dāng)為虛;缺省生成的類成員函數(shù);求值順序&序列點;類成員初始化順序&聲明順序;導(dǎo)致不可移植代碼的實現(xiàn)相關(guān)問題等。

本質(zhì)復(fù)雜性(不完全列表)

1. 內(nèi)存管理

2. 對象生命期

3. 重載決議

4. 名字查找

5. 模板參數(shù)推導(dǎo)規(guī)則

6. 異常

7. OO(動態(tài))和GP(靜態(tài))兩種范式的應(yīng)用場景和交互

總而言之,這一節(jié)的目的是要告訴你從一個較高的層次去把握C++中的復(fù)雜性。其中最重要的一個指導(dǎo)思想就是在學(xué)習(xí)的過程中注意你正學(xué)習(xí)的技術(shù)或細節(jié)到底是80%場景下的還是20%場景下的(一般來說,讀完兩本書——后面會提到——之后你就能夠很容易的對此進行判斷了),如果是20%場景下的(有大量這類復(fù)雜性,其中尤數(shù)各種各樣的workarounds為巨),那么也許最好的做法是只記住一個大概,不去作任何深究。此外,一般來說,不管使用哪門語言,認(rèn)識語言陷阱對于編程來說都是一個必要的條件,語言陷阱的特點是如果你掉進去了,那么很大可能意味著你本來就不知道這有個陷阱,后者很大可能意味著你不知道如何解決。

學(xué)習(xí)C++:實踐者的方法

在上面寫了那么多之后,如何學(xué)習(xí)C++這個問題的答案其實已經(jīng)很明顯了。我們所欠缺的是一個書單。

第一本

如果你是一個C++程序員,那么很大的可能性你會需要用到底層知識(硬件平臺架構(gòu)、緩存、指令流水線、硬件優(yōu)化、內(nèi)存、整數(shù)&浮點數(shù)運算等);這是因為兩個主要原因:一,了解底層知識有助于寫出高效的代碼。二,C++這樣的接近硬件的語言為了降低語言抽象的效率懲罰,在語言設(shè)計上作了很多折衷,比如內(nèi)建的有限精度整型和浮點型,比如指針。這就意味著,用這類語言編程容易掉進Joel所謂的“抽象漏洞”,需要你在語言提供的抽象層面之下去思考并解決遇到的問題,此時的底層知識便能幫上大忙。因此,一本從程序員(而不是電子工程師)的角度去介紹底層知識的書會非常有幫助——這就是推薦《Computer Systems:A Programmers Perspective》(以下簡稱CSAPP)(中譯本《深入理解計算機系統(tǒng)》)的原因。

第三本(是的,第三本)

另一方面,C++不同于C的一個關(guān)鍵地方就在于,C++在完全保留有C的高效的基礎(chǔ)上,增添了抽象機制。而所謂的“現(xiàn)代C++風(fēng)格”便是倡導(dǎo)正確利用C++的抽象機制和這些機制構(gòu)建出來的現(xiàn)代C++庫(以STL為代表)的,Bjarne也很早就倡導(dǎo)將C++當(dāng)作一門不同于C的新語言來學(xué)習(xí)(就拿內(nèi)存管理來說,使用現(xiàn)代C++的內(nèi)存管理技術(shù),幾乎可以完全避免new和delete),因此,一本從這個思路來介紹C++的入門書籍是非常必要的——這就是推薦《Accelerated C++》的原因(以下簡稱AC++)?!禔ccelerated C++》的作者Andrew Koenig是C++標(biāo)準(zhǔn)化過程中的核心人物之一。

第二本

C++是在C語言大行其道的歷史背景下發(fā)展起來的,在一開始以及后來的相當(dāng)長一段時間內(nèi),C++是C的超集,所有C的特性在C++里面都有,因此導(dǎo)致了大量后來的C++入門書籍都從C講起,實際上,這是一個誤導(dǎo),因為C++雖然是C的超集,然而用抽象機制擴展C語言的重大意義就在于用抽象去覆蓋C當(dāng)中裸露的種種語言特性,讓程序員能夠在一個更自然的抽象層面上編程,比如你不是用int*加一個數(shù)組大小n來表示一個數(shù)組,而是用可自動增長的vector;比如你不是用malloc/free,而是用智能指針和RAII技術(shù)來管理資源;比如你不是用一個只包含數(shù)據(jù)的結(jié)構(gòu)體加上一組函數(shù)來做一個暴露的類,而是使用真正的ADT。比如你不是使用second-class的返回值來表達錯誤,而是利用first-class的語言級異常機制等等。然而,C畢竟是C++的源頭,剝開C++的抽象外衣,底層仍然還是C;而且,更關(guān)鍵的是,在實際編碼當(dāng)中,有時候還的確要“C”一把,比如在模塊級的二進制接口封裝上。Bjarne也說過,OO/GP這些抽象機制只有用在合適的地方才是合適的。當(dāng)人們手頭有的是錘子的時候,很容易把所有的目標(biāo)都當(dāng)成釘子,有時候C的確能夠提供簡潔高效的解決方案,比如C標(biāo)準(zhǔn)庫里面的printf和fopen(此例受云風(fēng)的啟發(fā))的使用界面就是典型的例子。簡而言之,理解C語言的精神不僅有助于更好地理解C++,更理性地使用C++,而且也有其實踐意義——這就是推薦《The C Programming Language》(以下簡稱TCPL)的原因。此外,建議在閱讀《Accelerated C++》之前先閱讀《The C Programming Language》。因為,一,《The C Programming Language》非常薄。二,如果你帶著比較的眼光去看問題,看完《The C Programming Language》再看《Accelerated C++》,你便會更深刻的理解C++語言引入抽象機制的意義和實際作用。

第四本

《Accelerated C++》固然寫得非常漂亮,但正如所有漂亮的入門書一樣,它的優(yōu)點和弱點都在于它的輕薄短小。短短3百頁,對現(xiàn)代C++的運用精神作了極好的概述。然而要熟練運用C++,我們還需要更多的講解,這個時候一本全面但又不鉆語言牛角尖,從“語言是如何支持抽象設(shè)計”的角度而不是“為了講語言特性而講語言特性”的角度來介紹一門語言的書便至關(guān)重要,在C++里面,我還沒有見到比C++之父本人的《The C++ Programming Language》(以下簡稱TC++PL)做得更好的,C++之父本人既有大規(guī)模C++運用的經(jīng)驗又有語言設(shè)計思想的最本質(zhì)把握,因此TC++PL才能做到高屋建瓴,不為細節(jié)所累;同時又能做到實踐導(dǎo)向,不落于為介紹語言而介紹語言的巢臼。最后有一個需要提醒的地方,TC++PL其實沒有它看起來那么厚,因為真正介紹語言的內(nèi)容只有區(qū)區(qū)500頁(第一部分:基礎(chǔ);第二部分:抽象機制;以及第四部分:用C++設(shè)計),剩下的是介紹標(biāo)準(zhǔn)庫的,可以當(dāng)作Manual(參考手冊)。

建議3:CSAPP &TCPL& AC++&TC++PL。

是的,在C++方面登堂入室并不需要閱讀多得恐怖的所謂“經(jīng)典”,至于為什么這些“經(jīng)典”無需閱讀,前面已經(jīng)講的很詳細了。其實你只需要這四本書,就可以奠定一個深厚的基礎(chǔ),以及對C++的成熟理性的現(xiàn)代運用理念。其余的書都可以當(dāng)成參考資料,用到的時候再去翻閱,即:

建議4:實踐驅(qū)動地學(xué)習(xí)。

實踐驅(qū)動當(dāng)然不代表什么基礎(chǔ)都不打,直接捋起袖管就上。不管運用哪種工具,首先都需要知道關(guān)于它的一定程度的基本知識(包括應(yīng)該怎么用,和不應(yīng)該怎么用)。知道應(yīng)該怎么用可以幫你發(fā)揮出它的正確和最大效用,知道不應(yīng)該怎么用則可以幫你避免用的過程中傷及自身的危險。這就是為什么我建議你看四本書,以及建議你要了解C++中的陷阱(大部分來自C,因此你可以閱讀《C缺陷和陷阱》)的原因。

實踐驅(qū)動代表著一旦一個扎實的基礎(chǔ)具備了之后獲得延伸知識的方式。出于環(huán)境和心理的原因,C++學(xué)習(xí)者們在這條路上走錯的幾率非常大,許多人乃至以上來就拿Effective C++&More Effective C++、Inside C++ Object Model這類書去讀(是的,我也是,所以我才會在這里寫下這篇文章),結(jié)果讀了一本又一本,出現(xiàn)知道虛函數(shù)實現(xiàn)機制的每個細節(jié)卻不知道虛函數(shù)作用的情況。

實踐驅(qū)動其實很簡單:實踐+查文檔。知識便在這樣一個簡單的循環(huán)中積累起來。實踐驅(qū)動的最大好處就是你學(xué)到的都是實踐當(dāng)中真正需要的,屬于那“80%”最有用的。而查文檔的重要性前面已經(jīng)說過了,但對于C++實踐者來說,哪些“文檔”是非常重要的呢?

第二本

《C++ Coding Standard》。無需多作介紹,這是一本濃縮了C++社群多年來寶貴的經(jīng)驗結(jié)晶的書,貼近實踐,處處以80%場景為主導(dǎo),不鉆語言旮旯,用本為主…總之,非常值得放在手邊時時參閱。因為書很薄,所以也不妨先往腦袋里面裝一遍。書中的101條建議的介紹都很簡略,并且指出了詳細介紹的延伸閱讀,在延伸閱讀的時候還是要注意不要陷入無關(guān)的細節(jié)和不必要的技巧中,時時抬頭看一看你需要解決的問題。在C++編碼標(biāo)準(zhǔn)方面,Bjarne也有一些建議。

第一本

《The Pragmatic Programmer》,用本程序員的杰作;雖然不是一本C++的書,但其介紹的實踐理念卻是所有程序員都需要的。

第三本

《Code Complete, 2nd Edition》,這是一本非常卓越的參考資料,涉及開發(fā)過程的全景,有大量寶貴的經(jīng)驗。你未必要一口氣讀完,但你至少應(yīng)該知道它里面都寫了哪些內(nèi)容,以便可以回頭參閱。

其它

所有優(yōu)秀的技術(shù)書籍都是資料來源。一旦養(yǎng)成了查文檔的習(xí)慣,所有的電子書、紙書、網(wǎng)絡(luò)上的資源實際上都是你的財富。不過,查文檔的前提是你要從手邊的問題分析出應(yīng)該到什么地方去查資料,這里,分析問題的能力很重要,因此:

建議5:思考。

這個建議就把我們帶到了第四本書:

第四本:

《你的燈亮著嗎?》。不作介紹,自己閱讀,這本書只有一百多頁,但精彩非常,妙趣橫生。

最后,要想理性地運用一門語言,不僅需要看到這門語言的特點,還要能夠從另一個角度去看這門語言——即看到它的缺點,因為從心理上——

事實10:一旦我們熟悉了一門語言之后,就容易不知不覺地在其框架下思考,受到語言特性的細節(jié)的影響,作出second-class的設(shè)計。

對于像C++這樣的在抽象機制上作了折衷的語言,尤其如此,思考容易受到語言機制本身細節(jié)的影響,往往在心里頭還沒想好怎么抽象,就已經(jīng)確定了使用什么語言機制乃至技巧;更有甚者是為了使用某個特性而去使用某個特性。然而,實際上,我們應(yīng)該——

建議6:脫離語言思考,使用語言實現(xiàn)。

關(guān)于設(shè)計的一般理念,Eric Raymond在《The Art of Unix Programming》的第二部分有非常精彩的闡述。

此外,除了脫離語言的具體抽象機制來思考設(shè)計之外,學(xué)習(xí)其它語言對同類抽象機制的支持也是非常有益的,正如老話所說,“兼聽則明”。前一陣子reddit上也常出現(xiàn)“How Learning XXX help me become a Better YYY programmer”(其中XXX和YYY指代編程語言)的帖子,正是這個道理,這就把我們帶到了最后一個建議:學(xué)習(xí)其它語言。

建議7:學(xué)習(xí)其它語言。

如果你是一個系統(tǒng)程序員,你可能會覺得沒有必要學(xué)習(xí)其它語言,然而未必如此,你未必需要精通其它語言,而是可以去試著了解其它語言的設(shè)計理念,是如何支持日常編程中的設(shè)計的。這一招非常有利于在使用你自己的語言編程時心理上脫離語言機制細節(jié)的影響,作出更好的抽象設(shè)計。

尾聲

建議8(可選):重讀本文。

注:這篇文章的目的是給國內(nèi)的C++學(xué)習(xí)者(尤其是初學(xué)者)一個可操作的建議。我打算不斷修訂并完善它;因為這是根據(jù)我個人的經(jīng)驗來寫的,而基于我對C++的熟悉程度,可能會有地方并不能完完全全站到初學(xué)者的視角來看問題。


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7614

    瀏覽量

    137405

原文標(biāo)題:你應(yīng)當(dāng)如何學(xué)習(xí)C++(以及編程)

文章出處:【微信號:C_Expert,微信公眾號:C語言專家集中營】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    匯道科技淺談:學(xué)Java編程之前需要學(xué)習(xí)C++嗎?

    也不同,所以學(xué)Java編程之前不用學(xué)習(xí)c++。另一個角度,我們知道c++是比較復(fù)雜的。和c++在工業(yè)領(lǐng)域中所處的位置有關(guān)系。
    發(fā)表于 02-28 15:21

    初學(xué)者該如何學(xué)習(xí)C++

    的錯誤學(xué)習(xí)方法,很多人認(rèn)為學(xué)習(xí)方法真的是一抓一大把,關(guān)于這些編程語言的學(xué)習(xí)方法,程序員總是非常苦惱,想要找到一條符合自己學(xué)習(xí)的道路其實并沒有
    發(fā)表于 05-22 16:41

    學(xué)習(xí)c++的經(jīng)驗分享!

    ;b)只學(xué)而不堅持的人;16.把時髦的技術(shù)掛在嘴邊,還不如把過時的技術(shù)記在心里;17.C++不僅僅是支持面向?qū)ο蟮某绦蛟O(shè)計語言;18.學(xué)習(xí)編程最好的方法之一就是閱讀源代碼;19.在任何
    發(fā)表于 10-08 03:46

    如何學(xué)習(xí)C++,如何學(xué)好C++

    大家分享下我自己的學(xué)習(xí)心得與體會!Linus曾說過:“C++是一門很恐怖的語言,而比它更恐怖的是很多不合格的程序員在使用著它”,這個世界上最難的編程語言可能非C++莫屬了,呵呵,雖然有
    發(fā)表于 08-20 06:27

    如何學(xué)習(xí)編程c++語言?

      如何學(xué)習(xí)編程c++語言?粵嵌來講解嵌入式C語言在各種項目中要用到的知識點,尤其是嵌入式C語言之變量與常量的內(nèi)容:   1、變量類型和表示
    發(fā)表于 12-15 08:28

    學(xué)習(xí)C++方法以及C++的就業(yè)方向

    學(xué)習(xí)方向:嵌入式+人工智能嵌入式是一門技術(shù)學(xué)習(xí)目標(biāo)1.嵌入式開發(fā)概述;(面向?qū)ο笤谇度胧介_發(fā)中角色)2.嵌入式Linux C++編程;(C++
    發(fā)表于 12-24 07:32

    C++編程思想

    C++編程思想,很好的資料,大家下載看看吧!夠20字了吧,哈哈哈!
    發(fā)表于 11-17 11:38 ?0次下載

    C++“指針”學(xué)習(xí)建議

    C++“指針”學(xué)習(xí)建議
    發(fā)表于 03-31 15:53 ?3次下載

    如何提高cc++的安全編程能力?《CC++安全編碼》帶你詳細學(xué)習(xí)

    CC++安全編碼是C/C++安全編碼領(lǐng)域的權(quán)威著作,被視為“標(biāo)準(zhǔn)”參考書,由國際資深軟件安全專家撰寫,美國CERT主管親自作序推薦。本書結(jié)合國際標(biāo)準(zhǔn)
    發(fā)表于 08-28 08:00 ?0次下載

    C++編程調(diào)試秘笈

    C++編程調(diào)試秘笈資料下載。
    發(fā)表于 06-01 15:35 ?15次下載

    Linux C/C++ 學(xué)習(xí)路線

    一、秋招 Linux C/C++ offer 情況二、Linux C/C++ 方向的一些思考三、計算機基礎(chǔ)知識的梳理四、C++ 方向的深入
    發(fā)表于 11-06 19:36 ?14次下載
    Linux <b class='flag-5'>C</b>/<b class='flag-5'>C++</b> <b class='flag-5'>學(xué)習(xí)</b>路線

    CC++經(jīng)典著作-C專家編程.PDF

    CC++經(jīng)典著作-C專家編程.PDF
    發(fā)表于 12-13 17:11 ?0次下載

    CC++實物精選《C專家編程

    CC++實物精選《C專家編程
    發(fā)表于 01-17 09:55 ?0次下載

    C++學(xué)習(xí)筆記之c++的基本認(rèn)識

    自這篇文章我們即將開始C++的奇幻之旅,其內(nèi)容主要是讀C++ Primer的總結(jié)和筆記,有興趣可以找原版書看看,對于學(xué)習(xí)C++還是有很大幫助的。這篇文章將從一個經(jīng)典的程序開始介紹
    的頭像 發(fā)表于 03-17 13:57 ?757次閱讀

    c語言,c++,java,python區(qū)別

    操作系統(tǒng)、嵌入式系統(tǒng)等對性能要求較高的場景。C語言的語法相對簡單,學(xué)習(xí)曲線較平緩,也是學(xué)習(xí)其他高級語言的入門語言。 C++C++是在
    的頭像 發(fā)表于 02-05 14:11 ?2542次閱讀