這是一位同學寄到我郵箱裡面的一封信。應該說,這類C/C++入門學習的問題我回答過,隻是并沒有很具體到某個平台,某個語言,是以,我的回答可能給大家一種雲裡霧裡的感覺,指導性不強,是以,大家還是不斷問。我也隻有不斷回答。
其實呢,這裡面我自己也有一些苦衷。寫程式寫到我這麼久,看很多問題都抽象了,大家覺得很多風馬牛不相及的問題,在我看來,都是“一碼事”。
Windows和Linux作業系統,甚至其他的作業系統,我看起來,是“一碼事”。
VC和gcc,“一碼事”。
C和C++,“一碼事”。
彙編和進階語言,“一碼事”。
C++和Java,“一碼事”。
網絡傳輸和共享記憶體,“一碼事”。
程序和線程,“一碼事”。
程序和服務,“一碼事”。
。。。
甚至,我說個吓人的,站在“堆”的角度,“棧”和“隊列”,也是“一碼事”。
大家能了解不?
是以,每次大家一問到我很具體的問題,我就頭大,n多的朋友,直接一段代碼甩到我QQ或者email裡面,問肖老師,這段代碼為啥挂了?為啥有洩漏?我就快昏死過去了。呵呵。
我想這很好了解,大家剛剛開始接觸計算機軟體程式設計,從0(注意,不是O“偶”啊,呵呵)開始學習,看到很多新奇的東東,也學到很多新想法,這些東東呢,目前還沒有串起來,都是零散的知識點,是以,看問題“割裂”思維很嚴重,學東西也不透徹。問出問題來,目的性也很強,搞得我很不好回答。
就好比下面這位同學的問題。
不過呢,我想這是正常的,我也是從這條路走過來的,這不算什麼。其實軟體程式設計也就是一份工作啦,隻要潛心鑽研進去,好好學習,慢慢的,工作做多了,看到的東東多了,見識廣了,也就自然而然能站在一個較高的角度,“俯視”這個專業,那,自然很多東東,看起來就不難了。
我今天把這位朋友的信做個公開回答,我想,回答的問題其實并不重要,關鍵是,我希望大家能了解,如果能多學一點東東,以一種統攬的目光來看待問題,則很多問題,尤其是很多方向性問題,其實很容易解決的。
我想,這是一種思想,我寫文字,喜歡加點思想的東東進去,好比我的書《0bug-C/C++商用工程之道》一樣,大家都說這是一本程式書,其實,我這個作者說不是的。我真正想講的内容,其實在第一章,如何讓程式員掌握商用化開發和工程化開發的思想,能了解這個,其實,後面的内容我認為都不必細看的,因為自己遇到問題,都能提出解決方案,何苦來照抄我的?
技術是不值錢的,思想值錢。起碼我這麼認為。
好,言歸正傳,我們看看這位同學的來信,嗯,還是那句話哈,一家之言,歡迎拍磚,呵呵,别忘了。
原文如下:
肖老師:
你好,最近也許你很忙吧?不過我還是很榮幸,你看到我的信了。我的名字叫陳XX,在廣西桂林電子科技大學學習,專業是資訊與計算科學;我今年是大二的學生了,而且馬上進入大三了。今天是周未,在大學生大學營中找到了你的郵箱位址。其實我很想與你寫信了,隻是沒有找到你的郵箱位址啊!今天有幸看到《我們“憑什麼”找工作?》這文章後有個你的郵箱和QQ。
還是開門見山吧,其實我也很想成為一名程式員,不僅這個職業可以賺錢,而且我也越發現我喜歡上了這個職業。因為我們在大一學了C和C++。我覺得很上手。可是我還是很迷惘啊!怎麼說呢?因為我們學了上面的那兩和計算機語言。我就從上學期開始學MFC,還有相關的WinAPI。可是我覺得好難了。學了那麼久了我覺得沒有什麼進展的。很亂。我現在我覺得我選擇了這個,我還是想堅持下去,但是又很猶豫,一來因為我的數學不好,聽說做程式員的話要有比較好的數學功底才行,是不是這樣的一種情況呢?期待你的回答一下!
第二,我學習Windows下程式設計,MFC,要從哪裡下手,應該怎麼學才能夠有很好的進步呢?
第三,我們是資訊與計算科學專業,我們得知這個專業的學生就業不是很好,你覺得在這個專業裡我們如何安排剩下的時間才對呢?我們該向哪方面發展呢?
我是個農村出來的孩子,不怎麼懂得說話,今天能夠遇到你的确是我的榮幸啊!很期待你的回複,在此先謝謝你了。
陳XX
2010年3月13日
我的回答:
要我說,不管學C還是學C++,VC和gcc都可以,甚至,什麼其他C語言編譯器,也可以啊,Intel的C,以前DOS下的turbo C/C++,Watcom C/C++,都可以,我首先擺句話,C和C++是語言,既然是語言,就與作業系統無關,那些printf,scanf,甚至包括什麼對話框,MassageBox,消息循環,都不重要,因為這不是語言特性,初學者,暫時先不必管。
其實學語言,東西不多的。C語言裡面,常用的就那麼一些語句,嗯,幾乎所有的語言,都隻有那麼些語句。
你要有判斷語句吧,分支是程式設計很重要的,那if...else結構要學習一下。
循環,計算機裡面主要就是循環,while,for,得學習吧。
要有變量,則必然有指派語句,與之對應,有了變量就有了常量,那麼,#define的宏定義,const常量宣告,要學一點。
加減乘除基本四則計算要會吧,大家學計算機專業,什麼邏輯運算符要會吧?
程式要分段,每段呢,Basic叫子程式,或者子產品,C裡面叫函數,其他語言各有叫法,其實都是一碼事啦。
既然有了函數,或者子程式,“跳子”動作要了解吧,或者Call函數的動作要了解吧?就是我從主程式跳到一個子子產品執行,執行完畢後會自動傳回到調用處,繼續執行主程式,這個好了解吧?
然後呢?
沒啦!
真沒啦,熟練掌握上面的基本語句,你什麼語言其實都可以寫程式的。大家說對不?
Basic,彙編,C,等等,各種語言,在編制執行流程這部分,又有多大差别?
然後呢?學一點指針,C語言最拽的就是指針,沒指針,C就變Basic了,呵呵。
學指針,我給個新鮮點的建議,大家不妨試試。很多人站在進階語言的角度,了解指針确實困難,什麼嘛,指來指去的,腦子都亂了。
ok,我建議大家學習一點彙編語言,這方面書也很好找的,站在彙編角度去了解指針,一下就能了解,因為彙編裡面全是指針計算,你調入寄存器的值,是通過一個單元号來表示的,這就是指針。大家隻要用彙編實作一個連結清單,嗯,再多實作一個樹,我想,指針怎麼玩,再怎麼都會了。有興趣的朋友,不妨試試。
然後呢?呵呵,C學習完了,起碼我認為是這樣。
講到這裡,大家肯定罵聲一片,姓肖的這個江湖騙子,又在騙人了(某位網友送我的,呵呵),每本學習C語言的書,第一課,Hello World,你都不講,printf都不教,你這C語言就學完了?退學費!哦,肖老師沒收我學費,沒得退-_-
嗯,确實,如果大家要我講C語言,我是不講Hello World的,printf,是作業系統的東東哦,不屬于語言規範。因為它涉及輸入輸出流控制,而流這個概念,其實是作業系統提供給各種語言的通用控制台功能。不屬于語言範疇。
另外,不是每個作業系統都提供printf哦,Windows的視窗模式下,你用printf試試看,能不能打出東東來是以,我說句話,凡是和具體平台綁定的東東,其實通用性并沒有保障,學語言,學抽象,先學通用的東東好一點。
ok,我們再來看C++,嗯,C++博大精深,我這輩子是沒有學完的,我想,這個世界上恐怕也很少有程式員,寫程式曾經把C++的每一個特性都用一遍。那怎麼學?
我的回答是,學到夠用為止。
C++,最重要的是面向對象的思想,我想,學會這個,比什麼都重要。我們學C的程式設計,一件事情,先做什麼,後做什麼,起碼,我們是講得清楚的,也能寫出程式流程,這種分先後次序做事情的方法,是典型的面向過程。
面向對象在現代程式開發中很重要,大型工程,功能子產品太多,每個組織工具,全部然到一起,會亂的,bug也不好控制。是以,用對象,把一堆資料,以及它所有可能的操作方法,集合到一起,到哪都不會丢三落四的,這樣寫的代碼,品質高,效率也不錯,是個好的開發習慣。
其實面向對象很簡單,計算機裡面,做來做去都是計算,對不對?既然是計算,就少不了資料,是以,資料必有其特性啊,那麼,我們寫的函數子產品,可能适合這類資料,不适合那類資料,我們用對象把函數和它适合處理的資料,全部綁到一起,大家調用起來友善嘛。就這麼簡單。
還有個命名空間問題,這是C++的創造發明,同樣一個AddData,向一個集合裡面加資料,給隊列加的算法和給棧加的算法,就肯定不一樣,亂用就要出錯。C呢,命名上不容易區分,現在到了C++,“隊列.AddData()”和“棧.AddData”,大家看看,是不是一目了然?命名空間就是讓程式員好看不發昏的工具嘛。
了解了對象,那自然了解類,類是對象的程式描述,對象則是類程式在運作期,記憶體中執行個體化出來的一個具體有生命的程式工作段,一個類可以執行個體化一個對象,也可以執行個體化多個,各有其私有變量區,互相不然,同樣一個“人”這個類,我們可以執行個體化出張三李四王二麻子三個對象,都是合理的,了解不?
模闆就不多說了吧,其實就是“類的類”,模闆沒有界定類的一些特性,比如資料類型,那麼,哪天我們把int貼合到一個模闆上,可以得到一個int類,float也可以得到float類,再進一步執行個體化為int類對象和float類對象,就這麼簡單。大家不用想複雜了。
C++了解到這裡,我認為就夠了,剩下的,工作中有用到,邊看邊學啦,最核心的理念已經掌握了。
有一個重點,幾乎所有的C++編譯器,其實都是相容C和C++的,嗯,還有内嵌式彙編。那,寫程式有必要分得那麼開嗎?C++到函數内部,不就是C啦,C呢,我用函數指針+結構體,一樣可以實作對象的。這個世界正式因為有了這種複雜性和多樣性,才多姿多彩的。
是以,建議大家寫程式的時候,哪個語言合用用哪個,别形而上學,别鑽牛角尖,什麼語言都是假的,寫出程式來賣錢是真的,大家說是不是?
ok啦,我們終于可以回到這位同學的問題,咋從VC開始,用MFC寫Windows程式?
很簡單,按上面的流程走一遍,C和C++基本知識都不熟,上來就學windows開發,還要了解MFC,沒有學會走,就想跑,會摔跟鬥的。
學完上面的,要去看看Windows程式設計這本書,很經典的,這裡面啊,沒怎麼講MFC,但是,講了使用WinMain方式寫Windows程式的辦法,其實,這更符合傳統的C和C++,都要有個main才能開始運作吧。
不了解WinMain,上來就跑MFC,我敢說,你連你的程式從哪開始運作的都找不到。
WinMain很好了解的,上來先CteateWindowEx,就是建立一個視窗,這個函數巨複雜,不要背,我每次都是從别人代碼裡面拷貝一個過來,自己改吧改吧,視窗就出來了。
最重要的來了哈,Windows程式都是基于一個事件隊列在工作,也叫消息隊列,深刻了解消息隊列循環,要知道,每個視窗一出來,Windows系統就友情贈送了一個消息隊列服務給你,你按的鍵盤,點的滑鼠,還有其他一些什麼事件,都自動放到這個隊列中,我們程式的任務,就是建立一個死循環,不斷從隊列中彈出消息來處理就好了,至于有多少種消息,我告訴你,無數種,因為可以自定義,簡單看看Windows常用幾個,剩下的,以後碰到再查啦。
嗯,還是要給大家一個printf嘛,不然,大家想打點字元都打不出來,也太沒面子了,去查查AfxMessageBox這個函數,暫時應該夠用了,再不然,去看看GDI裡面的TextOut,是不是這個哦?好久沒用,記不清了。實在不行,VC下有個通用的,TRACE,這是列印到VC開發環境,就是IDE的Out視窗的,和printf用法一樣,夠了吧?
當我們把這些東東了解了,去看看侯捷先生的《深入淺出MFC》,怎麼從WinMain思想一下跳到MFC的架構思想,看完前三章就回了,後面幾章我都沒怎麼看,也夠用了,呵呵。
有個提示,去找本Win32API手冊,這個一般Windows開發是必備的,系統提供什麼功能函數,基本上都有,這中間要了解Handle的概念,句柄,很費解的,我當初也是很久都沒有了解到,直到有一天,有個大蝦一句話把我點醒了,“你把它當視窗的指針看好了!”,明白了吧,C和C++中,指針代表一切,什麼都可以指針表示,你就把Handle看做指針好了,就是一個視窗,一個資源,在系統中的唯一标示符,一個ID,一個指針。
再提示一點,Win32API的函數,MFC中基本上都有同名的對應函數,很多時候,看熟悉了,猜都猜得出MFC下一個對象,可能有哪些公有方法的。反過來也一樣,MFC熟了,可以逆推Wind32API裡面有啥函數。
and。。。沒啦!
又沒啦,使用VC,利用MFC開發Windows程式,把上面路程走一遍,就差不多了,要是書買的齊全,我覺得,三個月足以了,沒必要花太多時間。
當然,這樣開發商用工程還是不夠的,得大量的學習其他相關知識。
我們開發非模态視窗,要了解線程的,要了解并行開發,那就要了解鎖了,這個呢,是所有多任務作業系統都必須學習的開發知識,要想學習這個,我推薦我的書《0bug-C/C++商用工程之道》,第六章以後全在講這些知識,并行開發的知識。
我們開發圖形應用,要了解GUI,GDI對象,DirectX,這些都有專門的書,用了就學,不用就不學。
網絡估計是大家都少不了的,現在的話是,不懂TCP/IP開發,就不要學着别人出來闖江湖,呵呵,不過呢,學TCP最好的書不是Windows的,有本《Unix網絡程式設計》,第一卷和第二卷,經典到了極點,建議看看,看了,什麼Windows,Linux,都是一碼事。呵呵。
然後我話講完,洗洗睡了^_^