淺談學習C語言與學習C++語言的關係

本文寫給CC++語言初學者。

論壇中,常有初學者問“學C++語言前是否要先學C?”。我認爲這是個僞問題。問題本身的答案並不是提問人真正想要的。

回答問題本身很簡單:“當然不需要”。因爲C++是一門獨立的編程語言,它在語法、構建環境和運行環境上都無需依賴任何其它語言。至於說它是“C語言的超集”,那只是一種模糊的提法而已,更準確的說法應是:C++語言從設計之初就充分考慮了對C語言的兼容,結果它在很大程度上兼容了C語言。如此而已。

但對於那樣提問的初學者來說,以上會是他們想要的答案嗎?我覺得不是。至少問題沒有這麼簡單。

C++語言支持多種編程範式:面向過程、面向對象和範型程序設計。它所兼容C的部分,正是支持面向過程的主要部分。有C語言的基礎,雖然有助於更快地掌握C++的面向過程部分,但由於C++語言本身也直接支持面向過程,因此我們完全可以從C++中直接學習面向過程程序設計,而無需先學C。至少理論上如此。

但話又要說回來。注意,這麼提問的大多是初學者。一般講解C++語言的教程,限於篇幅,面向過程部分無法與一本優秀的C語言教程相媲美。於是,真正的問題來了:直接從C++語言開始學習的初學者,他是否願意像C語言初學者那樣花大量的時間和精力,專門鑽研面向過程程序設計呢?如果他不願,那麼他對面向過程部分的掌握,就難以跟一個紮紮實實學習過C語言的人相比。即使只討論“C++中的C”,結論也一樣。但是,這裏我只是想強調這樣一個事實,而並非要下個“必需先學C”的結論。

我個人在初學C++語言時,覺得教程中學到的好多東西,包括面向對象程序設計,在實踐中無法運用自如。後來因工作需要,又去學習Java語言,之後對面向對象有了一點開竅的感覺。再使用C++寫程序時,發現OO起來也更順暢了,我的好幾位朋友也有過類似的感覺。究其原因,我想跟上面的分析的C語言情況類似。C++的所支持的特性和編程範式太多,初學者很難快速消化全部。而Java1.4之前,可以認爲是純面向對象的。這樣,使用Java寫程序時,我們被迫實踐面向對象編程,這就好比使用C寫程序,我們被迫實踐面向過程一樣。而直接使用C++寫程序,沒有什麼“被迫”,我們也就缺少了相應的“專項強化訓練”。並非所有的人都需要這種“專項強化訓練”,但對於初學者,面對着需要掌握的複雜知識體系,它確能起到“分而治之”的作用,從而促進對知識的消化和吸收。

還有人認爲,學會了C++語言,自然就學會了C。而我並不認同這種觀點。我們必需承認兩點:第一,C語言是有用的,這不用多說,那麼多C語言構築起來的項目和複雜系統擺在那裏。雖然沒有對包括面向對象在內的各種更抽象的編程範式提供直接支持,但事實證明它能解決複雜問題;第二,C++語言的設計者所設計的是一門新式的語言,而不僅僅是一個“更好用的C”。這導致C++在繼承C語言的同時也要對它的各種特性做必要的揚棄。於是,就產生了很多這樣的情況:某種特性,在C語言中非常重要,但C++語言卻擁有一些新的特性來替代它,而且可能做得更好。這樣,原來C語言中的一些特性在C++語言中雖然還被兼容,卻被大大淡化,或不再提倡,甚至一些C++語言的教程中提都不提了。這方面的例子很多,比如“宏”,C++中有太多可以在各種不同的場合取代宏的東西;再比如可變參數,還有對指針的一些複雜使用等等。這些東西在C語言中卻非常重要,重要到成爲C語言之所以“有用”的直接原因之一。因爲這些原因,一個用慣了C++語言,而從沒單獨學習過C語言的人,如果有一天突然被要求去負責一個C語言項目,我不認爲他一定能輕鬆搞定。所以,我認爲“學會C++,自然也就學會了C”的觀點是沒有道理的。

有人說過,“C語言是結構化的彙編”,沒錯,它的功能、效率和可移植性都很好地達到了它的設計初衷,它對現實項目中的各種問題也都有它獨特的解決方式,而同樣的解決方式在C++語言中卻未必是恰當的(反之也成立)。換句話說,從解決實際問題的方式來看,這兩種語言誰也包含不了誰。我們學習語言最終不都是爲了解決實際問題嗎?那結論已經出來了:C++語言從語法上幾乎完全包含了C不代表它“真正”包含了C

反過來,一個熟練掌握了C語言的程序員,學習C++語言的情況又是怎樣的呢?正如前面分析過,C語言面向過程的“專項訓練”非常有助於迅速掌握C++語言的面向過程部分;而且,大多數人最終都在實際的軟件開發中運用編程語言,這使得任何語言的編程背景對其它新語言的學習都會有幫助,比如說學習BASIC也可以認爲對學習C++有幫助。但不同的語言畢竟是不同的語言,C語言和C++語言終歸體現了不同的編程思想,如果在學習C++語言的過程中,不能適時的忘記並跳出C,有時可能阻礙對C++編程思想的理解和掌握。

最後,有必要提一下,C語言在其最新的標準中還加入了一些新的特性,它們當中的一些C++語言沒有辦法直接“兼容”,甚至未來的C++語言也不一定會兼容它們。比如棧上分配的動態數組。

想說的就這些了,總結一下:

1)學習C++語言不需要以任何其它語言作爲基礎,包括C;但是,

2)不要指望學會了C++語言,就等於同時掌握C++C

3)也不要指望學過一遍C++語言,面向過程的編程水平就一下子可以跟上專門學習過C語言的程序員;

4)學好了C,對學習C++有很大的幫助,但要更好的學習C++語言並掌握其編程思想,有時需適時地忘記並跳出C

 

再濃縮一下,其實只想說一句話:CC++是兩門不同的編程語言,只是它們有較大的聯繫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章