《清華大學計算機系列教材:C++語言程序設計(第4版)》針對程序設計的初學者,以面向對象的程序設計思想為主線,以通俗易懂的方法介紹C++語言,引導讀者以最自然的方式,將人類習慣的面向對象的思維方法運用到程序設計中。主要內容包括程序設計基礎知識、類與對象的基本概念、繼承與多態、輸入輸出流,以及泛型程序設計。此外,本教材還介紹了一些常用數據結構基礎知識,使得讀者學習《清華大學計算機系列教材:C++語言程序設計(第4版)》后,能夠解決一些簡單的實際問題。整套教材語言生動、流暢,深入淺出。適用于各類學校的C++語言程序設計課程。
一、 版本說明
本書第1版于1999年出版,第2版于2001年出版,第3版于2003年出版。第4版是在前三版的基礎上,廣泛聽取了讀者和同行的建議,參考了最新的資料,并根據作者在授課過程中的經驗而形成的。第4版主要修改內容如下。
(1) 刪除了原來的第13章。
(2) 在第2~12章中,每章增加了一節“深度探索”,作為選學內容。
(3) 編寫了貫穿第4~10章的新的綜合實例“個人銀行賬戶管理程序”.
(4) 重新編寫了第10章。
二、 本書的編寫背景
C++語言是從C語言發展演變而來的一種面向對象的程序設計語言。C++語言的主要特點表現在兩個方面: 一是兼容C,二是支持面向對象的方法。
面向對象的程序設計(OOP)方法將數據及對數據的操作方法封裝在一起,作為一個相互依存、不可分離的整體--對象。對同類型對象抽象出其共性,形成類。類中的大多數數據,只能用本類的方法進行處理。類通過一個簡單的外部接口,與外界發生關系,對象與對象之間通過消息進行通信。這樣,程序模塊間的關系簡單,程序模塊的獨立性、數據的安全性具有良好的保障,通過繼承與多態性,使程序具有很高的可重用性,使得軟件的開發和維護都更為方便。
由于面向對象方法的突出優點,目前它已經成為開發大型軟件時所采用的主要方法。而C++語言是應用最廣泛的面向對象的程序設計語言之一。
長期以來,C++語言被認為是較難使用的專業開發語言,很少被作為入門語言來講授。那么C++語言與面向對象的程序設計方法是否真的是比較高深、難以掌握的技術嗎?不是的!
其實C語言產生的初期,也只被少數專業開發人員使用。但隨著計算機科學的發展,計算機技術已滲透到各學科的研究和應用之中,C語言已經被各專業的工程技術人員廣泛應用于本專業的科研開發,也被很多學校作為第一門程序設計語言來講授。C++全面兼容了C語言,同時提供了比C語言更嚴格更安全的語法。從這個意義上講,C++首先是一個更好的C語言。
C++語言是一個面向對象的編程語言,而面向對象的編程方法(OOP)一度被看作是一門比較高深的技術。這是因為在面向對象的系統分析(OOA)和面向對象的系統設計(OOD)理論出現之前,程序員要寫一個好的面向對象的程序,首先要學會運用面向對象的方法來認識問題和描述問題。現在,OOP的工作比較簡單了,認識問題域與設計系統成分的工作已經在系統分析和設計階段完成,OOP工作就是用一種面向對象的編程語言把OOD模型中的每個成分書寫出來。
面向對象方法的出現,實際上是程序設計方法發展的一個返璞歸真過程。軟件開發從本質上講,就是對軟件所要處理的問題域進行正確的認識,并把這種認識正確地描述出來。面向對象方法所強調的基本原則,就是直接面對客觀存在的事物來進行軟件開發,將人們在日常生活中習慣的思維方式和表達方式應用在軟件開發中,使軟件開發從過分專業化的方法、規則和技巧中回到客觀世界,回到人們通常的思維。
那么,學習C++語言是否應該首先學習C語言呢?不是的。雖然C++語言是從C語言發展而來的,但是C++本身是一個完整的程序設計語言,而且它與C語言的程序設計思想是完全不同的。我們學習的進程不必嚴格遵循科學技術的發展進程,只有盡快地掌握最新的理論和技術,才能站到巨人的肩膀上。
因此,我們認為,C++語言是可以作為程序設計的入門語言來學習的。
三、 本書的特色
本書的特色是內容全面、深入淺出、靈活剪裁、立體配套。
本書是一本面向廣大初學者的入門教材,自1999年第一版出版以來,已經在清華大學等100多所學校的不同專業中使用,取得了良好的教學效果。
本書將C++語言作為計算機編程入門語言,不僅詳細介紹了語言本身,而且介紹了常用的數據結構和算法、面向對象的設計思想和編程方法、UML建模語言。全書以面向對象的程序設計方法貫穿始終,每一章都是首先闡述面向對象的程序設計思想和方法,由實際問題入手,然后引出必要的語法知識,在講解語法時著重從程序設計方法學的角度講述其意義和用途。本書的宗旨是,不僅要使讀者掌握C++語言本身,而且要能夠對現實世界中較簡單的問題及其解決方法用計算機語言進行描述。當然,要達到能夠描述較復雜的問題域還需要學習面向對象的軟件工程課等其他課程。
針對初學者和自學者的特點,本書力求做到深入淺出,將復雜的概念用簡潔淺顯的語言娓娓道來。不同學校可以針對自身的教學特點,選擇不同的章節組合進行教學。如果學時較少,可以只選擇第1~8章、第11章。每一章的深度探索也是選學內容,可以根據不同專業的教學需求進行選擇。
作者使用本書授課時的講課學時數為32學時,實驗學時數為32學時,課外上機學時數為32學時,課內外共96學時,每學時45分鐘。建議講課學時數分配如下:
第1章2學時,第2章4學時,第3章2學時,第4章4學時,第5章2學時,第6章4學時,第7章2學時,第8章2學時,第9章4學時,第10章2學時,第11章2學時,第12章2學時。
實驗學時數的分配請參考配套的《C++語言程序設計習題與實驗指導》.
讀者還可以通過配套的《C++語言程序設計學生用書》,在實踐中達到對內容的深入理解和熟練掌握。為了方便教師備課,本書還配有電子教案(PPT文件).
四、 內容摘要
第1章 緒論: 從發展的角度概要介紹了面向對象程序設計語言的產生和特點,面向對象方法的由來和主要的基本概念,并簡單介紹了什么是面向對象的軟件工程。最后介紹了信息在計算機中的表示和存儲以及程序的開發過程。
第2章 C++簡單程序設計: 講述C++程序設計的基礎知識。首先簡要介紹C++語言的發展歷史及其特點,接著學習構成C++語句的基本部分: 字符集、關鍵字、標識符、操作符等。還有C++的基本數據類型和自定義數據類型,以及算法的控制結構: 順序、選擇和循環結構。“深度探索”介紹變量的實現機制和C++表達式的執行原理。
第3章 函數: 講述C++語言的函數。在面向對象的程序設計中,函數對處理問題過程的基本抽象單元,是對功能的抽象。同時,使用函數也為代碼的重用提供了技術上的支持。主要從應用的角度講述各種函數的定義和使用方法。“深度探索”介紹運行棧與函數調用的執行、函數聲明與類型安全。
第4章 類與對象: 首先介紹面向對象程序設計的基本思想及其主要特點: 抽象、封裝、繼承和多態。接著圍繞數據封裝這一特點,著重講解面向對象設計方法的核心概念--類。其中包括類的定義、實現以及如何利用類來解決具體問題。最后,簡單介紹了如何用UML語言描述類的特性。“深度探索”介紹位域、用構造函數定義類型轉換,以及對象作為函數參數和返回值的傳遞方式。
第5章 數據的共享與保護: 講述標識符的作用域和可見性及變量、對象的生存期;使用局部變量、全局變量、類的數據成員、類的靜態成員和友元來實現數據共享,共享數據的保護,以及使用多文件結構來組織和編寫程序,解決較為復雜的問題。“深度探索”介紹常成員函數的聲明原則、代碼的編譯連接與執行過程。
第6章 數組、指針與字符串: 討論數組、指針與字符串。數組和指針是C++語言中最常用的復合(構造)類型數據,是數據和對象組織、表示的最主要手段,也是組織運算的有力工具。本章首先介紹數組、指針的基本概念和動態存儲分配以及動態數組對象。接著圍繞數據和對象組織這一問題,著重講解如何通過使用數組和指針解決數據、函數以及對象之間的聯系和協調。對于字符串及其處理,本章重點介紹string類。“深度探索”介紹指針與引用的聯系、指針的安全性隱患及其應對方案,以及const_cast的應用。
第7章 繼承與派生: 講述類的繼承特性。圍繞派生過程,著重討論不同繼承方式下的基類成員的訪問控制問題、添加構造函數和析構函數。接著討論在較為復雜的繼承關系中,類成員的唯一標識和訪問問題。“深度探索”介紹組合與繼承的區別與聯系、派生類對象的內存布局,以及基類向派生類的轉換及其安全性問題。
第8章 多態性: 講述類的另一個重要特性--多態性。多態是指同樣的消息被不同類型的對象接收時導致完全不同的行為,是對類的特定成員函數的再抽象。C++支持的多態有多種類型,重載(包括函數重載和運算符重載)和虛函數是其中主要的方式。“深度探索”介紹多態類型與非多態類型的區別、運行時類型識別機制,以及虛函數動態綁定的實現原理。
第9章 群體類和群體數據的組織: 群體是指由多個數據元素組成的集合體。群體可以分為兩大類: 線性群體和非線性群體。本章介紹幾種常用的群體類模板。
本章討論的群體的組織問題,指的是對數組元素的排序與查找方法。排序(sorting)又稱分類或整理,是將一個無序序列調整為有序的過程。查找(searching)是在一個序列中,按照某種方式找出需要的特定數據元素的過程。最后“深度探索”介紹模板的實例化機制、為模板定義特殊的實現。
第10章 泛型程序設計與C++標準模板庫: 泛型程序設計就是將程序寫得盡可能通用,同時并不損失效率。本章簡單介紹C++標準模板庫(STL)中涉及的一些概念、術語,以及它的結構、主要的組件的使用方法。重點介紹容器、迭代器、算法和函數對象的基本應用。目的是使讀者對STL與泛型程序設計方法有一個概要性的了解。“深度探索”深入介紹深復制與淺復制的問題,另外還介紹了STL組件的類型特征與STL的擴展問題,以及Boost庫。
第11章 流類庫與輸入輸出: 講述流的概念,然后介紹流類庫的結構和使用。就像C語言一樣,C++語言中也沒有輸入輸出語句。但C++編譯系統帶有一個面向對象的I/O軟件包,它就是I/O流類庫。“深度探索”介紹寬字符、寬字符串與寬流,以及對象的串行化問題。
第12章 異常處理: 講述異常處理問題。異常是一種程序定義的錯誤。C++中,異常處理是對所能預料的運行錯誤進行處理的一套實現機制。try,throw和catch語句就是C++語言中用于實現異常處理的機制。有了C++異常處理,程序可以向更高的執行上下文傳遞意想不到的事件,這樣程序能更好地從這些異常事件中恢復過來。“深度探索”介紹異常安全性問題和避免異常發生時的資源泄漏。
五、 作者分工
本書第1~3章和第9, 11, 12章由鄭莉編寫,第4~8章由董淵、鄭莉共同編寫,第10章由何江舟編寫,各章的綜合實例和深度探索由何江舟編寫,全書例題由何江舟調試。傅仕星、張瑞豐、田榮牌、孟鴻利、劉才良參加了部分編寫工作。另外特別感謝譚浩強教授和王行言教授審閱了本書第2版,并提出了許多寶貴建議。
感謝讀者選擇使用本書,歡迎您對本書內容提出意見和建議,我們將不勝感激。作者的電子郵件地址: zhengli@mail.tsinghua.edu.cn,來信標題請包含“C++book" .
作者2010年3月 于清華大學
第1章 緒論1
1.1 計算機程序設計語言的發展1
1.1.1 機器語言與匯編語言1
1.1.2 高級語言2
1.1.3 面向對象的語言2
1.2 面向對象的方法2
1.2.1 面向對象方法的由來3
1.2.2 面向對象的基本概念4
1.3 面向對象的軟件開發5
1.3.1 分析5
1.3.2 設計5
1.3.3 編程6
1.3.4 測試6
1.3.5 維護6
1.4 信息的表示與存儲6
1.4.1 計算機的數字系統6
1.4.2 幾種進位記數制之間的轉換8
1.4.3 信息的存儲單位10
1.4.4 二進制數的編碼表示11
1.4.5 定點數和浮點數15
1.4.6 數的表示范圍15
1.4.7 非數值信息的表示16
1.5 程序開發的基本概念16
1.5.1 基本術語16
1.5.2 完整的程序過程17
1.6 小結18
習題18
第2章 C++簡單程序設計19
2.1 C++語言概述19
2.1.1 C++的產生19
2.1.2 C++的特點20
2.1.3 C++程序實例20
2.1.4 字符集21
2.1.5 詞法記號22
2.2 基本數據類型和表達式23
2.2.1 基本數據類型24
2.2.2 常量25
2.2.3 變量27
2.2.4 符號常量28
2.2.5 運算符與表達式28
2.2.6 語句37
2.3 數據的輸入與輸出37
2.3.1 I/O流37
2.3.2 預定義的插入符和提取符37
2.3.3 簡單的I/O格式控制38
2.4 算法的基本控制結構39
2.4.1 用if語句實現選擇結構39
2.4.2 多重選擇結構41
2.4.3 循環結構44
2.4.4 循環結構與選擇結構的嵌套49
2.4.5 其他控制語句52
2.5 自定義數據類型52
2.5.1 typedef聲明53
2.5.2 枚舉類型enum53
2.6 深度探索55
2.6.1 變量的實現機制55
2.6.2 C++表達式的執行原理58
2.7 小結60
習題60
第3章 函數64
3.1 函數的定義與使用64
3.1.1 函數的定義64
3.1.2 函數的調用65
3.1.3 函數的參數傳遞78
3.2 內聯函數81
3.3 帶默認形參值的函數82
3.4 函數重載84
3.5 C++系統函數86
3.6 深度探索89
3.6.1 運行棧與函數調用的執行89
3.6.2 函數聲明與類型安全94
3.7 小結95
習題96
第4章 類與對象98
4.1 面向對象程序設計的基本特點98
4.1.1 抽象98
4.1.2 封裝99
4.1.3 繼承100
4.1.4 多態100
4.2 類和對象100
4.2.1 類的定義101
4.2.2 類成員的訪問控制102
4.2.3 對象103
4.2.4 類的成員函數104
4.2.5 程序實例106
4.3 構造函數和析構函數107
4.3.1 構造函數107
4.3.2 復制構造函數109
4.3.3 析構函數113
4.3.4 程序實例114
4.4 類的組合116
4.4.1 組合116
4.4.2 前向引用聲明120
4.5 UML圖形標識122
4.5.1 UML簡介122
4.5.2 UML類圖123
4.6 結構體和聯合體129
4.6.1 結構體129
4.6.2 聯合體130
4.7 綜合實例--個人銀行賬戶管理程序133
4.7.1 類的設計133
4.7.2 源程序及說明134
4.8 深度探索137
4.8.1 位域137
4.8.2 用構造函數定義類型轉換139
4.8.3 對象作為函數參數和返回值的傳遞方式140
4.9 小結143
習題144
第5章 數據的共享與保護146
5.1 標識符的作用域與可見性146
5.1.1 作用域146
5.1.2 可見性150
5.2 對象的生存期150
5.2.1 靜態生存期150
5.2.2 動態生存期151
5.3 類的靜態成員153
5.3.1 靜態數據成員154
5.3.2 靜態函數成員156
5.4 類的友元158
5.4.1 友元函數160
5.4.2 友元類161
5.5 共享數據的保護163
5.5.1 常對象163
5.5.2 用const修飾的類成員164
5.5.3 常引用166
5.6 多文件結構和編譯預處理命令168
5.6.1 C++程序的一般組織結構168
5.6.2 外部變量與外部函數170
5.6.3 標準C++庫172
5.6.4 編譯預處理173
5.7 綜合實例--個人銀行賬戶管理程序176
5.8 深度探索180
5.8.1 常成員函數的聲明原則180
5.8.2 代碼的編譯連接與執行過程182
5.9 小結185
習題185
第6章 數組、指針與字符串188
6.1 數組188
6.1.1 數組的聲明與使用188
6.1.2 數組的存儲與初始化190
6.1.3 數組作為函數參數193
6.1.4 對象數組194
6.1.5 程序實例196
6.2 指針199
6.2.1 內存空間的訪問方式199
6.2.2 指針變量的聲明200
6.2.3 與地址相關的運算“?”和“&" 200
6.2.4 指針的賦值201
6.2.5 指針運算203
6.2.6 用指針處理數組元素205
6.2.7 指針數組206
6.2.8 用指針作為函數參數209
6.2.9 指針型函數210
6.2.10 指向函數的指針211
6.2.11 對象指針213
6.3 動態內存分配218
6.4 用vector創建數組對象224
6.5 深復制與淺復制226
6.6 字符串229
6.6.1 用字符數組存儲和處理字符串230
6.6.2 string類230
6.7 綜合實例--個人銀行賬戶管理程序234
6.8 深度探索241
6.8.1 指針與引用241
6.8.2 指針的安全性隱患及其應對方案243
6.8.3 const_cast的應用246
6.9 小結248
習題248
第7章 繼承與派生251
7.1 類的繼承與派生251
7.1.1 繼承關系舉例251
7.1.2 派生類的定義252
7.1.3 派生類生成過程254
7.2 訪問控制256
7.2.1 公有繼承256
7.2.2 私有繼承258
7.2.3 保護繼承260
7.3 類型兼容規則262
7.4 派生類的構造和析構函數264
7.4.1 構造函數265
7.4.2 復制構造函數267
7.4.3 析構函數268
7.5 派生類成員的標識與訪問270
7.5.1 作用域分辨符270
7.5.2 虛基類276
7.5.3 虛基類及其派生類構造函數278
7.6 程序實例--用高斯消去法解線性方程組279
7.6.1 算法基本原理279
7.6.2 程序設計分析280
7.6.3 源程序及說明281
7.6.4 運行結果與分析286
7.7 綜合實例--個人銀行賬戶管理程序287
7.7.1 問題的提出287
7.7.2 類設計288
7.7.3 源程序及說明289
7.7.4 運行結果與分析294
7.8 深度探索295
7.8.1 組合與繼承295
7.8.2 派生類對象的內存布局298
7.8.3 基類向派生類的轉換及其安全性問題301
7.9 小結303
習題304
第8章 多態性306
8.1 多態性概述306
8.1.1 多態的類型306
8.1.2 多態的實現306
8.2 運算符重載307
8.2.1 運算符重載的規則308
8.2.2 運算符重載為成員函數309
8.2.3 運算符重載為非成員函數313
8.3 虛函數315
8.3.1 一般虛函數成員316
8.3.2 虛析構函數319
8.4 純虛函數與抽象類321
8.4.1 純虛函數321
8.4.2 抽象類322
8.5 程序實例--變步長梯形積分算法求解函數的定積分324
8.5.1 算法基本原理324
8.5.2 程序設計分析325
8.5.3 源程序及說明326
8.5.4 運行結果與分析329
8.6 綜合實例--對個人銀行賬戶管理程序的改進329
8.7 深度探索335
8.7.1 多態類型與非多態類型335
8.7.2 運行時類型識別337
8.7.3 虛函數動態綁定的實現原理340
8.8 小結343
習題344
第9章 群體類和群體數據的組織346
9.1 函數模板與類模板347
9.1.1 函數模板347
9.1.2 類模板350
9.2 線性群體353
9.2.1 線性群體的概念353
9.2.2 直接訪問群體--數組類355
9.2.3 順序訪問群體--鏈表類363
9.2.4 棧類368
9.2.5 隊列類374
9.3 群體數據的組織377
9.3.1 插入排序377
9.3.2 選擇排序379
9.3.3 交換排序380
9.3.4 順序查找381
9.3.5 折半查找381
9.4 綜合實例--對個人銀行賬戶管理程序的改進382
9.5 深度探索385
9.5.1 模板的實例化機制385
9.5.2 為模板定義特殊的實現388
9.5.3 模板元編程簡介392
9.6 小結395
習題395
第10章 泛型程序設計與C++標準模板庫398
10.1 泛型程序設計及STL的結構398
10.1.1 泛型程序設計的基本概念398
10.1.2 STL簡介399
10.2 迭代器402
10.2.1 輸入流迭代器和輸出流迭代器403
10.2.2 迭代器的分類405
10.2.3 迭代器的區間407
10.2.4 迭代器的輔助函數409
10.3 容器410
10.3.1 容器的基本功能與分類410
10.3.2 順序容器412
10.3.3 關聯容器427
10.4 函數對象435
10.4.1 函數對象基本概念及分類436
10.4.2 函數適配器441
10.5 算法447
10.5.1 STL算法基礎448
10.5.2 不可變序列算法448
10.5.3 可變序列算法451
10.5.4 排序和搜索算法455
10.5.5 數值算法459
10.6 綜合實例--對個人銀行賬戶管理程序的改進461
10.7 深度探索467
10.7.1 swap467
10.7.2 STL組件的類型特征與STL的擴展469
10.7.3 Boost簡介476
10.8 小結478
習題478
第11章 流類庫與輸入輸出481
11.1 I/O流的概念及流類庫結構481
11.2 輸出流483
11.2.1 構造輸出流對象483
11.2.2 使用插入運算符和操縱符484
11.2.3 文件輸出流成員函數488
11.2.4 二進制輸出文件490
11.2.5 字符串輸出流491
11.3 輸入流492
11.3.1 構造輸入流對象492
11.3.2 使用提取運算符493
11.3.3 輸入流操縱符493
11.3.4 輸入流相關函數493
11.3.5 字符串輸入流497
11.4 輸入輸出流498
11.5 綜合實例--對個人銀行賬戶管理程序的改進498
11.6 深度探索503
11.6.1 寬字符、寬字符串與寬流503
11.6.2 對象的串行化507
11.7 小結510
習題510
第12章 異常處理512
12.1 異常處理的基本思想512
12.2 C++異常處理的實現512
12.2.1 異常處理的語法513
12.2.2 異常接口聲明515
12.3 異常處理中的構造與析構516
12.4 標準程序庫異常處理517
12.5 綜合實例--對個人銀行賬戶管理程序的改進520
12.6 深度探索523
12.6.1 異常安全性問題523
12.6.2 避免異常發生時的資源泄漏525
12.7 小結528
習題529