摘要:C++是應用最廣的編程語言,C++的應用水平代表著一個國家的軟件產業發展水平,但是C++是最難掌握的編程語言。本文認為,只有自覺地把C、C++和數據結構作為一個整體,才能解決C++學習難的問題。
關鍵詞:C語言;C++語言;數據結構;重用程度
中圖分類號:G642文獻標識碼:B
文章編號:1672-5913 (2007) 20-0074-03
C++是計算機軟件領域中應用最廣的編程語言,包括操作系統、設備驅動、編譯器、系統工具、圖像處理、數據庫系統以及通用辦公軟件等在內的能夠代表一個國家軟件產業發展水平的基礎軟件都是適合C++應用的領域,因此,C++的應用水平代表著一個國家的軟件產業發展水平。不僅如此,C++具有的既可以針對底層硬件設計又可以面向應用軟件設計的功能使它成為我們深入分析、理解和應用其它各種軟件的方法,學好C++,再學用其它軟件就容易多了,用侯捷的話說,“萬千使用者前赴后繼的動力是:一旦學成,妙用無窮”。
C++也是最難掌握的編程語言。一是內容多:C++新標準出現之后,“一個覆蓋面非常廣闊的庫現在成了標準C++的一部分,其中包括以前稱為STL(標準模板庫)的內容。新的string類型、一組順序和關聯容器類型(比如vector、list、map和set),以及在這些類型上進行操作的一組可擴展的泛型算法(generic algorithm),都是這個新標準的特性”[1]。二是語法和語義不易理解:C++程序要由C++編譯器在語言層面上展開,例如,程序員設計的很多函數并不在程序員程序中被調用,而是在展開之后的內部C++程序表現中被調用,這與傳統的結構化程序設計完全不同,令很多人感到困惑,他們抱怨C++編譯器說:“它在你的背后做事情”[2],而C++很多令人疑惑的概念都和C++編譯器有關。本文認為,只有從C、C++和數據結構作為一個整體出發,才能解決C++學習難的問題。
1數據結構是語言研究的對象
長期以來,C、C++和數據結構都是相互獨立的課程:C與C++的聯系僅僅限于C++與C兼容,而主要強調的還是它們在方法上的截然不同;數據結構強調不依賴任何編程語言的描述,并且更多的是用類語言即非編程語言描述,即便使用了編程語言,也僅是作為描述數據結構的工具。C++標準的出現,迫使我們重新審視它們之間的關系。
當我們說,數據結構不依賴任何編程語言的描述,或者說,編程語言僅僅是描述數據結構的工具,那是為了不受編程語言的語法細節的影響,以突出典型算法的設計和算法的時間復雜度分析。但是,如果重點研究的是數據結構代碼的重用性,那么數據結構不僅必須用編程語言描述,而且還必須研究用什么編程語言描述才能提高數據結構代碼的重用程度、使語言能夠進一步發展的問題。我們要學習的C++標準庫以及建立其上的重用程度更高的泛型算法都是這種研究的成果。在這里,數據結構不再是編程語言描述的對象,而是編程語言研究的對象,是編程語言的一部分。用個比喻來說,研究資本主義生產活動中的人和研究解剖學意義下的人,意義是不同的。
數據結構作為語言的研究對象,要求我們按照語言發展的規律去研究它。語言發展是語言重用程度不斷提高:從匯編語言,C語言,到C++,Java的流行,是基礎設計方法重用程度的提高;從指令語句到函數,從對象到構件,支持重用的語言機制日漸成熟。按照語言發展規律去研究,就是“從事物的發展、‘自己運動’、變化中來觀察事物” [3],即從事物的關系和它的必然發展去觀察事物本身。Bruce Eckel教授在他的Thinking in C++(C++編程思想)一書中說:“由于很多人學習走了彎路,因此,我們已經開始探索C程序員轉移到C++語言性能層上的方法” [4]。他先用C語言實現一個袖珍C庫(一個簡化的順序結構),然后再轉換為C++實現,由此進入C++。他認為,“C++的主要設計目標之一是使庫容易使用。這意味著,在C中使用庫有困難。懂得這一點就對C++設計有了初步的了解,從而對如何使用它有了更深入的認識”[4]。其實,這不僅對C程序員,而且對任何想學好C++的人來說,都是重要的。
2數據結構領我們從C走進C++
Bruce Eckel教授從軟件發展的角度,揭示了C、C++和結構的聯系:C需要創建結構,但是C語言結構不能像語言內部類型一樣使用,這不利于軟件重用程度的進一步提高,于是,“用戶從設計自定義數據類型開始擴展C語言” [5],“C++對C的結構體類型作了實質性的擴充” [5]。可以說,“C++的許多性能都圍繞著一個根本的思想:創建新的數據類型的能力”[4]。這里需要闡明結構和數據結構的關系:結構是變量集合體,數據結構指向量、集合、樹、圖、代數方程、多項式等典型離散結構,也可以說,是典型算法依賴的結構,或者說,是服務于典型算法的結構,數據結構和算法是相互依存的。從語言上講,結構包含數據結構,從算法上講,結構指數據結構。
Bruce Eckel教授實際上提示了學習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程序員自覺能動的活動即實踐解除了。“凡是把理論引向神秘主義的神秘東西,都能在人的實踐中以及對這個實踐的理解中得到合理的解決” [6]。以結構串(簡化的)為例,表1和表2顯示了從C描述到C++描述的部分轉換內容。
3學習中的辯證思維
概括起來說,C、C++和數據結構是相互包含的整體。辯證法所說的相互包含或某物中包含他物,并不是指他物作為一個現成的細小的東西包含在某物中,而是作為某物的一個方面、一種趨勢、一種因素包含在某物中。C包含C++,是指C包含著C++作為其必然的發展。C++包含C是因為它是更好的C,例如,C++的向量類模板std::vector就是更好的C數組,C++類串就包含著C文本串。“每一種事物都有它的特殊的否定方式,經過這樣的否定,它同時就獲得發展,每一種觀念和概念也是如此”[7]。在這個意義上講,C、C++和數據結構的學習是統一的。
Bruce Eckel教授雖然意識到他自己提出的從順序結構的C描述到C++描述的轉換在引入C++概念時的重要作用,但是他沒有理解其中所包含的全部意義,自然也沒有完全按照上述的分析去做,而是把重點放在引導讀者從C++編譯器實現匯編代碼的角度反向審視C++的語法和語義。為了使匯編代碼簡單,他只得使用“玩具例子”,從而讓他最初想法中的許多積極因素從中流失了。
在C++的學習或授課過程過程,我們會受到各式各樣思想的影響。而要把C、C++和數據結構作為為一個有機的整體,必須堅持辯證思維。我們遇到問題,都有自己的思想,無論愿意還是不愿意,有意還是無意,都受某種哲學的支配,問題只在于,我們愿意接受哪一種哲學的支配。對自然科學的成就,辯證唯物主義不去概括,唯心主義、形而上學等哲學就會去總結。常常是,我們自以為得意的、甚至時髦的觀點,其本質卻是在幾百年前就已經提出了的、早已在哲學上被廢棄了的命題。例如,程序設計原理發展之快已經超越了人們的適應能力[5],這是現在流行的、雖然表達多種多樣但實質相同的不可知論,它阻礙了我們按照辯證法的要求在程序設計領域內去揭示這個不斷的轉變過程的運動規律的實踐。又例,“世界是由對象構成的,因此,面向對象的程序設計方法用人們看待現實世界的方法來表達計算機程序”[13]。那么請問,世界一開始就是由對象構成的,為什么面向對象的程序設計方法出現在二十世紀末,而不是更早,為了回答這個問題,就必須回到程序設計這個特殊的領域中來,仔細研究該領域中各個方面的關系和它們的發展,把現實的需要和為了滿足需要所做的現實的努力即人的能動的活動包括到C++概念的完美的定義中去,這樣我們就等于回到了辯證的思維上來。
愿有志學好C++的人,能夠做一個自覺的辯證唯物主義者。


參考文獻
[1] 潘愛民,張麗. C++ Primer第三版(中文版)[M]. 北京:中國電力出版社,2004.
[2] 侯捷. 深度探索C++對象模型[M]. 武昌:華中科技大學出版社,2001.
[3] 余源培. 時代精神的精華—馬克思主義哲學原著導讀(下冊)[M]. 上海:復旦大學出版社,1992.
[4] 劉宗田,邢大紅,孫慧杰. C++編程思想[M]. 北京:機械工業出版社,2001.
[5] 林麗閔,別紅霞. 標準C++寶典[M]. 北京:電子工業出版社,2001.
[6] 馬克思恩格斯選集(第一卷). 北京:人民出版社,1995.
[7] 馬克思恩格斯選集(第三卷). 北京:人民出版社,1995.
作者簡介:天津師范大學副教授,于南開大學數學系獲理學學士學位,主講C/C++與數據結構課程,主持天津市教委項目“計算機基礎課程體系改革”,主編教材《C/C++與數據結構》第3版(上下冊),獲國家十一五規劃教材,由清華大學出版社出版。