程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 從深度和廣度談C++的復雜度

從深度和廣度談C++的復雜度

編輯:C++入門知識

C++到底有多復雜,沒有人知道,我們知道的,只是C++很復雜。但是再復雜的事情也有解決的方法,對於C++的復雜度,我們可以從C++的“深度”與“廣度”來探究。

C++有一個樸素的思想:“簡單的問題用簡單的方法解決,復雜的問題,用復雜的方法解決。”。這句話當然不能絕對化。一個問題的復雜性,往往有多種來源,比如可以是“深度”上的困難;從這一點上,我們了解,證明“任何一個>=6之偶數,都可以表示成兩個奇質數之和 ”是個難題,雖然題目很短一讀明白,但它確實是一個復雜的問題,因為它是“哥德巴赫猜想”。

復雜度的來源也可以是問題的“廣度”。比如給一個人做一道可口的菜是簡單的,但今天是周末,我家來了七大姑八大姨,站在廚房裡的我就會感覺面臨一道復雜的問題。我不僅要了解每一位親人的口味,並不絕不能做八道菜,讓客人各選所需就算了。八個簡單的問題,交叉在一起時,成就了一道“眾口難調”的復雜的問題。

C++中所具備的復雜功能,一小部分有助於我們解決深度上的復雜問題,但更多的功能,是為用來對付“廣度”上問題。這符合軟件開發行業的主要市場需求。

小結一下:C++中有很多復雜的(方法或)知識點其實是留著對付一些復雜問題的。但,我們在學習C++時,我們能遇上什麼“復雜”問題嗎?答:很少,甚至就是沒有。那麼,光靠一些簡單的問題,我們能理解那些復雜的方法嗎?

比如“面向對象”。C++之父早說過,C++語言不是,也不願意成為一門單純的“面向對象”的語言。為什麼?因為“簡單的事情簡單解決。”,“面向對象”的編程思想,在歷史上出現,就是為了解決足夠龐大的復雜問題才提出,並且確實取得了一定程度上的成功。於是乎人人都對它趨之若骛,更是成為了大學編程專業的必修課。但請問,你根本就沒可能在書本上遇上任何足以體現“面向對象”之必要性的問題,你怎麼學習“面向對象”呢?請注意,寫一個“非常面向對象”的程序,是很容易地,一個java版本的“Hello world”程序就很OO。但把程序寫得非常有“面向對象”的風格,這絕對不是我們的目標。目標是解決問題,“面向對象”是一種“思想工具”,當我們判斷再沒有更簡單的工具來解決一個問題時,於是把手伸入機器貓的口袋,叮叮铛……屏幕上打出四個大字“面向對象”。

有同學要舉手反對了,復雜度是相對啊。一個在大拿眼裡,很簡單的,用面向過程可以非常漂亮地解決的問題,但在初學者面前,就是一個大廣度的問題,這時,作為一種組織方法,“面向對象”不能幫我們些什麼嗎?如果能幫上,那我們用它來學習“面向對象”,就不算是紙上談兵了吧?

完全同意。像Linus這樣的大牛,操作系統這樣既深又廣的問題,他都覺得用C語言這樣典型的面向過程的語言,就可以輕易拿下,他倒覺得像C++這樣的語言的OO,純是添亂。

復雜度當然是相對的,但當我們面臨,或者說期望的復雜是指“廣度”上的復雜度時,普通教程上的那種一桿子想把C++語言捅到底的教學內容與教學方式,就顯得非常的不夠用了。寫一個“俄羅斯方塊”的程序,就是一個“相對復雜”的問題。翻開一本《C++ Primer》,740多頁,如果僅僅從C++語言知識點來看,任何一個學到第227頁的讀者,都應該要開始動手寫一個俄羅斯方塊的程序。因為那時候他已經懂得多維數組,於是可以定義出方塊數據;他已經懂得if判斷,於是寫得出碰撞判斷;他已經學會for循環,於是知道如何消掉被填滿的一行或多行……

有人覺得我這是“忽悠”。他們又改口說,“俄羅斯方塊”是一個太復雜的問題了,如果學生在學習半途花上一個月時間去搞一個俄羅斯方塊,會節外生枝,徹底打亂原來學習計劃雲雲。好吧我承認確實存在苦研十年軍事理論,然後殺上戰場一舉成名的將軍;但我更願意相信多數將軍是不斷地打一場場小戰役,不斷地在晚上挑燈看《武穆遺書》的過程中成長起來的。而我也確實看到那些在一個月中,被“俄羅斯方塊”程序搞得頭破血流,並堅持下來的學生,確實在日後遇上問題時,有著更好的“糾纏”能力。試想一下吧,學完《C++ Primer》200多頁時,像樣的問題都沒遇上一個,卻要再翻過那麼一百多頁,然後開始學習“第三部分 類和數據抽象”。

我用《C++ Primer》當教材當老師,不是一次兩次了,但每當我開始兜售“面向對象的本質不是封裝、不是派生、不是多態,而是抽象”時,我總覺得自己是那麼無力。底下的戰士,他們沒有打過任何一場像樣的戰役,但他們希望在課堂上成長為巴頓,成長為陳庚。

在那一時,我總會想起C++之父痛心地說到C++教育的一句話,大意是說:現在C++教育似乎進入了一個怪圈:要教會一個人C++,唯一的辦法,就是把他教成C++高手。我在從事C++教育時,很長時間,發現自己一樣落在怪圈裡!長歎。

(以上內容,任何有正常理智或心態的人,都不會認為:本文作者在說《C++ Primer》是一本差書。)

對一個初學者,學完《C++ Primer》227頁之後,動手寫一個俄羅斯方塊游戲,復雜在哪裡?

(一),C++初學者(沒有其它語言學習經驗)那時剛剛把類型、變量、數組、指針、if、for………裝入腦裡,每一個知識點都才剛剛開始消化,這時要把這一切摻合到一起,去解決一個真正的問題,就像一個剛剛看完《高爾夫球桿使用說明》的人上了場,那個亂勁兒!

(二),沒有人會覺得寫一個字符界面的俄羅斯方塊很爽,所以總得要去碰一下圖形用戶界面的編程知識吧。窗口、菜單、定時器、消息、GDI,資源文件……媽啊。就這一點就夠廣的。

(三)、教材裡那些花花草草小貓小草的例程,也確實拿來過調試,什麼單步跟蹤、什麼斷點、什麼變量觀察……還有什麼條件編譯、二分法、以及如何使用Windows的調試API,比如“OutputDebugString”函數等等,平常老師在台上講,我們都覺得需要那麼多調試方法嗎?現在可好,程序好不容易編譯通過,一運行就死了,一頭霧地才開始想如何調試……

公元一九八九年,有人問總設計師說中國十年改革開放最大的失誤是什麼?他說是教育。(公元2008?)有人問C++之父,十數年,C++語言最大的失誤是什麼?Stroustrup說,也是教育。這個“也”字純屬我加的。原文得是這樣:

Stroustrup Says C++ Education Needs To Improve :

“在C++的早期,我很擔心不能足夠快的教好教師。我有理由擔心,因為許許多多明顯的C++的錯誤使用都可以追蹤到教育者自身對基礎的誤解。我未能足夠清晰的闡述我的想法和原理。”Stroustrup表示,“我避免傳授‘如何思考’,我猜想最好的教育之法是使用大量優秀的例子。”

沒錯,如果可能,就永遠別去教學生如何“面向對象”,而是要讓他們陷在問題的海洋裡,再加上有力的引導,最終讓他們自己悟出面向對象的真谛。

如果我有兒子。當他成長到對愛情似懂非懂的青澀年齡時,我不想對他講一堆什麼愛情啊責任啊的大道理。我也不希望他談第一個女朋友,就馬上順利地步入婚姻,我希望如果可能,他最好遇上些嫌貧愛富的女人,遇上些虛榮乖張的女人,然後被女人拋棄過,或拋棄過別人,然後命運再安排他遇上他的灰姑娘。

花花公子,情海裡幾度沉浮,不輕易付出感情的男人,通常比那些遇上第一個女人就愛得死去活來的青澀男孩,更懂得愛情的真谛,在婚後也往往更不會愛上別的女人。為什麼,因為隨便碰上個異性就愛得死去活來的人,通常他們愛的不是人,他們愛的是“愛情”這個東西,就算他們其實沒有足夠了解愛情中另一個人。

作為C++程序員,碰上任何一個問題,就要來扯上一通“面向對象”如何如何的人;在碰上真正問題時,往往比那些懂得簡單問題簡單解決的人,掛得早。因為他們的出發點是愛上了“面向對象”,而不是了解所要解決的問題。

同樣的,作為一個C++愛好者,你可以愛上C++,但作為一個程序員,請別輕易說,我愛上了一門語言。愛容易讓人盲目;一個盲目的fans,是有力量的,他全身心地投入了學習,真好;但一個盲目的程序員,是可怕的,他會以為,C++和愛情一樣,無所不能。

但具體到我個人,我有我的堅持,我決不願意把我的學生培養成C++的粉絲(但,成為C++之父BS的粉絲,我熱烈支持:)。相反,我會“折磨”他們,《白話 C++》中的第二章《准備》,已經成功地讓很多學習者,發出哀怨:“學習C++,有必要去安裝、編譯這麼多庫嗎? 還是Java好,一切都准備好了。”

《准備篇》的緒言,是一句煽情的話:“決定你能否成為程序員,不在於你的計算機基礎,在於你是否有足夠的耐心。”

現在社會,有些女人或男人,會同時和幾個異性談戀愛,他們是勢利的。我當然也反對這種不道德的行為。但如果是學習語言(無論是編程語言或自然語言),如果你有能力,我建議完全可以同時學習兩門,學習上越“勢利”越好,而有能力時,同時學習多門語言,那是相當的有利可圖,具體有機會再展開。通常一個人對在C++語言熟練之後,就具備了這個能力。對於從沒有學習過其它編程語言的初學者,同時學習C++語言之外,還要學習另一門,不現實。但是,當我們僅僅限定C++編程的范疇,那就一定不能癡癡,長期地把精力和愛心都放在語言自身上。

C++之所以復雜,是因為C++的“深度”與“廣度”都很深遠,但是遵循“有一定深度,擴大廣度,有一定廣度,加深度”的方法,會發現C++的“深度”與“廣度”會成為我們編程中的一點樂趣。希望本文會給讀者帶來收獲。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved