從深度和廣度談C++的復(fù)雜度
C++到底有多復(fù)雜,沒有人知道,我們知道的,只是C++很復(fù)雜。但是再?gòu)?fù)雜的事情也有解決的方法,對(duì)于C++的復(fù)雜度,我們可以從C++的“深度”與“廣度”來探究。
C++有一個(gè)樸素的思想:“簡(jiǎn)單的問題用簡(jiǎn)單的方法解決,復(fù)雜的問題,用復(fù)雜的方法解決。”。這句話當(dāng)然不能絕對(duì)化。一個(gè)問題的復(fù)雜性,往往有多種來源,比如可以是“深度”上的困難;從這一點(diǎn)上,我們了解,證明“任何一個(gè)>=6之偶數(shù),都可以表示成兩個(gè)奇質(zhì)數(shù)之和 ”是個(gè)難題,雖然題目很短一讀明白,但它確實(shí)是一個(gè)復(fù)雜的問題,因?yàn)樗恰案绲掳秃詹孪搿薄?/p>
復(fù)雜度的來源也可以是問題的“廣度”。比如給一個(gè)人做一道可口的菜是簡(jiǎn)單的,但今天是周末,我家來了七大姑八大姨,站在廚房里的我就會(huì)感覺面臨一道復(fù)雜的問題。我不僅要了解每一位親人的口味,并不絕不能做八道菜,讓客人各選所需就算了。八個(gè)簡(jiǎn)單的問題,交叉在一起時(shí),成就了一道“眾口難調(diào)”的復(fù)雜的問題。
C++中所具備的復(fù)雜功能,一小部分有助于我們解決深度上的復(fù)雜問題,但更多的功能,是為用來對(duì)付“廣度”上問題。這符合軟件開發(fā)行業(yè)的主要市場(chǎng)需求。
小結(jié)一下:C++中有很多復(fù)雜的(方法或)知識(shí)點(diǎn)其實(shí)是留著對(duì)付一些復(fù)雜問題的。但,我們?cè)趯W(xué)習(xí)C++時(shí),我們能遇上什么“復(fù)雜”問題嗎?答:很少,甚至就是沒有。那么,光靠一些簡(jiǎn)單的問題,我們能理解那些復(fù)雜的方法嗎?
比如“面向?qū)ο蟆薄++之父早說過,C++語言不是,也不愿意成為一門單純的“面向?qū)ο蟆钡恼Z言。為什么?因?yàn)椤昂?jiǎn)單的事情簡(jiǎn)單解決。”,“面向?qū)ο蟆钡?a href="http://m.1cnz.cn/v/tag/1315/" target="_blank">編程思想,在歷史上出現(xiàn),就是為了解決足夠龐大的復(fù)雜問題才提出,并且確實(shí)取得了一定程度上的成功。于是乎人人都對(duì)它趨之若騖,更是成為了大學(xué)編程專業(yè)的必修課。但請(qǐng)問,你根本就沒可能在書本上遇上任何足以體現(xiàn)“面向?qū)ο蟆敝匾缘膯栴},你怎么學(xué)習(xí)“面向?qū)ο蟆蹦?請(qǐng)注意,寫一個(gè)“非常面向?qū)ο蟆钡某绦颍呛苋菀椎兀粋€(gè)java版本的“Hello world”程序就很OO。但把程序?qū)懙梅浅S小懊嫦驅(qū)ο蟆钡娘L(fēng)格,這絕對(duì)不是我們的目標(biāo)。目標(biāo)是解決問題,“面向?qū)ο蟆笔且环N“思想工具”,當(dāng)我們判斷再?zèng)]有更簡(jiǎn)單的工具來解決一個(gè)問題時(shí),于是把手伸入機(jī)器貓的口袋,叮叮鐺……屏幕上打出四個(gè)大字“面向?qū)ο蟆薄?/p>
有同學(xué)要舉手反對(duì)了,復(fù)雜度是相對(duì)啊。一個(gè)在大拿眼里,很簡(jiǎn)單的,用面向過程可以非常漂亮地解決的問題,但在初學(xué)者面前,就是一個(gè)大廣度的問題,這時(shí),作為一種組織方法,“面向?qū)ο蟆辈荒軒臀覀冃┦裁磫?如果能幫上,那我們用它來學(xué)習(xí)“面向?qū)ο蟆保筒凰闶羌埳险劚税?
完全同意。像Linus這樣的大牛,操作系統(tǒng)這樣既深又廣的問題,他都覺得用C語言這樣典型的面向過程的語言,就可以輕易拿下,他倒覺得像C++這樣的語言的OO,純是添亂。
復(fù)雜度當(dāng)然是相對(duì)的,但當(dāng)我們面臨,或者說期望的復(fù)雜是指“廣度”上的復(fù)雜度時(shí),普通教程上的那種一桿子想把C++語言捅到底的教學(xué)內(nèi)容與教學(xué)方式,就顯得非常的不夠用了。寫一個(gè)“俄羅斯方塊”的程序,就是一個(gè)“相對(duì)復(fù)雜”的問題。翻開一本《C++ Primer》,740多頁,如果僅僅從C++語言知識(shí)點(diǎn)來看,任何一個(gè)學(xué)到第227頁的讀者,都應(yīng)該要開始動(dòng)手寫一個(gè)俄羅斯方塊的程序。因?yàn)槟菚r(shí)候他已經(jīng)懂得多維數(shù)組,于是可以定義出方塊數(shù)據(jù);他已經(jīng)懂得if判斷,于是寫得出碰撞判斷;他已經(jīng)學(xué)會(huì)for循環(huán),于是知道如何消掉被填滿的一行或多行……
有人覺得我這是“忽悠”。他們又改口說,“俄羅斯方塊”是一個(gè)太復(fù)雜的問題了,如果學(xué)生在學(xué)習(xí)半途花上一個(gè)月時(shí)間去搞一個(gè)俄羅斯方塊,會(huì)節(jié)外生枝,徹底打亂原來學(xué)習(xí)計(jì)劃云云。好吧我承認(rèn)確實(shí)存在苦研十年軍事理論,然后殺上戰(zhàn)場(chǎng)一舉成名的將軍;但我更愿意相信多數(shù)將軍是不斷地打一場(chǎng)場(chǎng)小戰(zhàn)役,不斷地在晚上挑燈看《武穆遺書》的過程中成長(zhǎng)起來的。而我也確實(shí)看到那些在一個(gè)月中,被“俄羅斯方塊”程序搞得頭破血流,并堅(jiān)持下來的學(xué)生,確實(shí)在日后遇上問題時(shí),有著更好的“糾纏”能力。試想一下吧,學(xué)完《C++ Primer》200多頁時(shí),像樣的問題都沒遇上一個(gè),卻要再翻過那么一百多頁,然后開始學(xué)習(xí)“第三部分 類和數(shù)據(jù)抽象”。
我用《C++ Primer》當(dāng)教材當(dāng)老師,不是一次兩次了,但每當(dāng)我開始兜售“面向?qū)ο蟮谋举|(zhì)不是封裝、不是派生、不是多態(tài),而是抽象”時(shí),我總覺得自己是那么無力。底下的戰(zhàn)士,他們沒有打過任何一場(chǎng)像樣的戰(zhàn)役,但他們希望在課堂上成長(zhǎng)為巴頓,成長(zhǎng)為陳庚。
在那一時(shí),我總會(huì)想起C++之父痛心地說到C++教育的一句話,大意是說:現(xiàn)在C++教育似乎進(jìn)入了一個(gè)怪圈:要教會(huì)一個(gè)人C++,唯一的辦法,就是把他教成C++高手。我在從事C++教育時(shí),很長(zhǎng)時(shí)間,發(fā)現(xiàn)自己一樣落在怪圈里!長(zhǎng)嘆。
(以上內(nèi)容,任何有正常理智或心態(tài)的人,都不會(huì)認(rèn)為:本文作者在說《C++ Primer》是一本差書。)
對(duì)一個(gè)初學(xué)者,學(xué)完《C++ Primer》227頁之后,動(dòng)手寫一個(gè)俄羅斯方塊游戲,復(fù)雜在哪里?
(一),C++初學(xué)者(沒有其它語言學(xué)習(xí)經(jīng)驗(yàn))那時(shí)剛剛把類型、變量、數(shù)組、指針、if、for………裝入腦里,每一個(gè)知識(shí)點(diǎn)都才剛剛開始消化,這時(shí)要把這一切摻合到一起,去解決一個(gè)真正的問題,就像一個(gè)剛剛看完《高爾夫球桿使用說明》的人上了場(chǎng),那個(gè)亂勁兒!
(二),沒有人會(huì)覺得寫一個(gè)字符界面的俄羅斯方塊很爽,所以總得要去碰一下圖形用戶界面的編程知識(shí)吧。窗口、菜單、定時(shí)器、消息、GDI,資源文件……媽啊。就這一點(diǎn)就夠廣的。
(三)、教材里那些花花草草小貓小草的例程,也確實(shí)拿來過調(diào)試,什么單步跟蹤、什么斷點(diǎn)、什么變量觀察……還有什么條件編譯、二分法、以及如何使用Windows的調(diào)試API,比如“OutputDebugString”函數(shù)等等,平常老師在臺(tái)上講,我們都覺得需要那么多調(diào)試方法嗎?現(xiàn)在可好,程序好不容易編譯通過,一運(yùn)行就死了,一頭霧地才開始想如何調(diào)試……
公元一九八九年,有人問總設(shè)計(jì)師說中國(guó)十年改革開放最大的失誤是什么?他說是教育。(公元2008?)有人問C++之父,十?dāng)?shù)年,C++語言最大的失誤是什么?Stroustrup說,也是教育。這個(gè)“也”字純屬我加的。原文得是這樣:
Stroustrup Says C++ Education Needs To Improve :
“在C++的早期,我很擔(dān)心不能足夠快的教好教師。我有理由擔(dān)心,因?yàn)樵S許多多明顯的C++的錯(cuò)誤使用都可以追蹤到教育者自身對(duì)基礎(chǔ)的誤解。我未能足夠清晰的闡述我的想法和原理。”Stroustrup表示,“我避免傳授‘如何思考’,我猜想最好的教育之法是使用大量?jī)?yōu)秀的例子。”
沒錯(cuò),如果可能,就永遠(yuǎn)別去教學(xué)生如何“面向?qū)ο蟆保且屗麄兿菰趩栴}的海洋里,再加上有力的引導(dǎo),最終讓他們自己悟出面向?qū)ο蟮恼嬷B。
如果我有兒子。當(dāng)他成長(zhǎng)到對(duì)愛情似懂非懂的青澀年齡時(shí),我不想對(duì)他講一堆什么愛情啊責(zé)任啊的大道理。我也不希望他談第一個(gè)女朋友,就馬上順利地步入婚姻,我希望如果可能,他最好遇上些嫌貧愛富的女人,遇上些虛榮乖張的女人,然后被女人拋棄過,或拋棄過別人,然后命運(yùn)再安排他遇上他的灰姑娘。
花花公子,情海里幾度沉浮,不輕易付出感情的男人,通常比那些遇上第一個(gè)女人就愛得死去活來的青澀男孩,更懂得愛情的真諦,在婚后也往往更不會(huì)愛上別的女人。為什么,因?yàn)殡S便碰上個(gè)異性就愛得死去活來的人,通常他們愛的不是人,他們愛的是“愛情”這個(gè)東西,就算他們其實(shí)沒有足夠了解愛情中另一個(gè)人。
作為C++程序員,碰上任何一個(gè)問題,就要來扯上一通“面向?qū)ο蟆比绾稳绾蔚娜?在碰上真正問題時(shí),往往比那些懂得簡(jiǎn)單問題簡(jiǎn)單解決的人,掛得早。因?yàn)樗麄兊某霭l(fā)點(diǎn)是愛上了“面向?qū)ο蟆保皇橇私馑鉀Q的問題。
同樣的,作為一個(gè)C++愛好者,你可以愛上C++,但作為一個(gè)程序員,請(qǐng)別輕易說,我愛上了一門語言。愛容易讓人盲目;一個(gè)盲目的fans,是有力量的,他全身心地投入了學(xué)習(xí),真好;但一個(gè)盲目的程序員,是可怕的,他會(huì)以為,C++和愛情一樣,無所不能。
但具體到我個(gè)人,我有我的堅(jiān)持,我決不愿意把我的學(xué)生培養(yǎng)成C++的粉絲(但,成為C++之父BS的粉絲,我熱烈支持:)。相反,我會(huì)“折磨”他們,《白話 C++》中的第二章《準(zhǔn)備》,已經(jīng)成功地讓很多學(xué)習(xí)者,發(fā)出哀怨:“學(xué)習(xí)C++,有必要去安裝、編譯這么多庫(kù)嗎? 還是Java好,一切都準(zhǔn)備好了。”
《準(zhǔn)備篇》的緒言,是一句煽情的話:“決定你能否成為程序員,不在于你的計(jì)算機(jī)基礎(chǔ),在于你是否有足夠的耐心。”
現(xiàn)在社會(huì),有些女人或男人,會(huì)同時(shí)和幾個(gè)異性談戀愛,他們是勢(shì)利的。我當(dāng)然也反對(duì)這種不道德的行為。但如果是學(xué)習(xí)語言(無論是編程語言或自然語言),如果你有能力,我建議完全可以同時(shí)學(xué)習(xí)兩門,學(xué)習(xí)上越“勢(shì)利”越好,而有能力時(shí),同時(shí)學(xué)習(xí)多門語言,那是相當(dāng)?shù)挠欣蓤D,具體有機(jī)會(huì)再展開。通常一個(gè)人對(duì)在C++語言熟練之后,就具備了這個(gè)能力。對(duì)于從沒有學(xué)習(xí)過其它編程語言的初學(xué)者,同時(shí)學(xué)習(xí)C++語言之外,還要學(xué)習(xí)另一門,不現(xiàn)實(shí)。但是,當(dāng)我們僅僅限定C++編程的范疇,那就一定不能癡癡,長(zhǎng)期地把精力和愛心都放在語言自身上。
C++之所以復(fù)雜,是因?yàn)镃++的“深度”與“廣度”都很深遠(yuǎn),但是遵循“有一定深度,擴(kuò)大廣度,有一定廣度,加深度”的方法,會(huì)發(fā)現(xiàn)C++的“深度”與“廣度”會(huì)成為我們編程中的一點(diǎn)樂趣。希望本文會(huì)給讀者帶來收獲。
-
C++
+關(guān)注
關(guān)注
22文章
2114瀏覽量
73773
原文標(biāo)題:從深度和廣度談C++的復(fù)雜度
文章出處:【微信號(hào):C_Expert,微信公眾號(hào):C語言專家集中營(yíng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論