前 言C Programming: a Q & A Approach 新生經常發現閱讀計算機語言書很困難,書寫本書的目的就是為了解決這個困難。如果能使學生深入到書本中,激發他們的興趣,并使得他們思考C語言的用法和含義,那么我們就可以把學習的過程變得簡單且有趣。為此,我們使用了Q&A的方式。在這個過程中,學生經常問的問題也會激發讀者的思考。通過直接并清晰地回答這些問題,我們把讀者的注意力集中到C編程中重要的概念上。 我們也觀察到很多計算機語言書很少有圖。因為可視化的圖形在教學中非常有用,所以我們努力使圖示既準確又容易理解。對于程序執行的操作,這些圖有利于澄清概念,加強學生對概念的理解。特別地,我們用三維的圖來描述循環和判斷結構,從而讓學生可以很快地掌握程序的流程。我們相信這些圖是對標準流程圖的加強。我們也意識到對于很多學生來說,指針是最困難的部分。指針圖示建立在包含變量名字、類型、地址和值的表格的基礎之上,并且表格出現在文本解釋的前面。本書中,我們使用表格來說明一個內存單元的信息是如何與另一個內存單元的信息聯系起來的。 很多書包含大量的代碼,但是并沒有給出充分的解釋,大部分新生不能也不愿意在沒有解釋的情況下獨立地理解哪怕是很簡單的代碼。本書在代碼中引導學生了解操作以及生成代碼的過程,目的就是使學生意識到哪些地方需要額外的想法,以及掌握正確細節的重要性。 這種獨特的方式已經受到用過本書草稿的學生的熱烈歡迎。本書也被推薦給其他學生并詢問他們的意見。當和其他書比較時,學生會優先選擇我們的書。我們相信你在教學和學習過程中也會發現本書的價值。 本書組織第1章介紹編程基礎,假設學生除了會使用計算機進行簡單的文字處理以外,沒有其他的計算機知識。第1章介紹了編程語言的概念,描述了硬件、信息在內存中的存儲方法、計算機語言、編譯器和軟件工程。本章的目標是使學生了解計算機的工作方式和軟件設計背后的概念。 第2章到第4章討論了過程語言的基本概念、基本語法和控制結構,也介紹了C庫函數和它們的用法。第5章介紹了用戶定義函數,強調了模塊化和可重用代碼的概念,簡單介紹了指針,并將它用在一個傳遞地址的函數中。本章最后,介紹了使用C語言用戶定義函數的效果。 第6章關注數值型數組。 第7章描述了字符串和指針。由于字符串使用地址進行管理,這一章也非常適合用來解釋如何利用指針修改內存。第8章覆蓋了C語言中的結構及其在生成鏈表、堆棧、隊列及二叉樹中的用法。另外,本章也介紹了大型程序設計,因為工程問題通常都很大。使用C特性來處理大型程序是公司招聘學生開發商用軟件產品時的一項重要考量。 第9章是關于C++語言的介紹。因為已經介紹過C,所以更多地介紹C++中面向對象編程的核心概念。我們用簡單的術語介紹了類、封裝和多態。這一章有很多演示,簡單的語言和豐富的演示為學生提供了很多使用C++基本特性的背景知識。 大部分章節被分為兩個部分——課程和應用程序。課程部分學習語法、格式和基本構造,應用程序部分演示課程中教授的知識如何用于解決實際問題,演示了開發的流程,目標是使學生能遵循結構化方法來開發自己的程序。 特點1)本書使用簡單的問答方式,學生會發現這種方式比講解的方式更加友好、更易于理解。這種方法式下,作者能夠發現學生經常問的問題并能簡潔地回答這些問題。 2)每一課都以一個樣例程序開始:源代碼并附有一些指示。學生根據指示觀察代碼的細節,從而了解C語言。下一步給出輸出以及解釋。解釋環節給出一系列的問答以解釋源代碼做了什么。 3)應用程序部分演示了C語言如何用于解決工程和計算機科學中的問題。我們詳細地解釋了它們。例子主要涉及程序設計、軟件工程、模塊化和生成可重用代碼。 4)給出大量的圖來演示編程的概念。很多圖都是獨一無二的,能讓學生快速地掌握概念。 5)在應用程序部分描述了四步結構化方法(引入了字符串和更復雜的數據結構后變成了五步結構化方法)。方法包括生成結構流程圖和數據流程圖。 6)應用程序部分也包括數值方法例子,這些例子用在把編程和數值方法結合起來的課程中。 7)課程部分包含注釋代碼,以幫助學生理解程序的細節和流程,使學生關注代碼并把代碼中的重要部分高亮顯示。 8)我們意識到學生一般不會主動閱讀多頁代碼,所以應用程序部分的每一段代碼都只有2到3頁,并有對應的解釋。 9)指針的概念很難理解。為了讓學生理解指針,可視化圖形是非常有用的。盒子中一個指針指向另外一個盒子,這種圖是不夠的。使用表格和網格狀的內存草圖,可以降低指針的神秘性。我們發現閱讀本書后,學生能夠輕松地理解指針的概念。 10)應用程序部分后的練習可以用于實驗課。教師可以讓學生提前閱讀特定的應用程序。上實驗課時,可以指導學生做一些改動練習,后續的部分可以作為家庭作業。 11)新生通常會在調試的時候遇到困難,因為他們對這個過程很陌生。新生也會感到很沮喪,因為他們必須要調試自己的第一個程序。為此,我們在第1章介紹了一個詳細的調試例子。初學者也發現調試循環是很困難的,本書中關注循環并演示了循環中值是如何變化的。學生將學習如何追蹤循環并發現錯誤。另外,初學者經常會犯的錯誤也在本書相應的位置指出。 12)每課后面的判斷題(有答案)可以讓學生快速評價自己對基礎知識的掌握程度。 13)每章后面的應用練習可以作為家庭作業。 14)本書中所有的程序都可以從www.mheducation.asia/olc/cprogramming獲取。學生可以修改并執行這些程序以理解它們是如何運行的。 15)第9章是有關C++的介紹,不僅討論了基礎知識,閱讀完本章后,學生還將學會使用面向對象編程的很多基本功能。 16)很多應用程序介紹了數值方法。 如何使用本書對于學生在第1章,你會理解什么可以保存在內存中,編譯器如何工作,軟件工程的步驟,最重要的是,編寫自己的第一個C程序。其他章討論了C語言編程。章節的課程都以一個簡短的介紹開始,指導你關注源代碼中一些重要的知識點。然后你可以閱讀源代碼和其中的注解。你甚至可以運行代碼并觀察程序的行為。完成這些后,確保你理解本課中主要的概念。之后閱讀解釋部分并完成判斷題和簡答題。如果做不好練習,應重新學習本課以消除疑問。 掌握了一章的課程后,開始學習應用程序部分,其目的是演示編寫程序的一般過程以及C的實際用處。你會發現,當你寫程序的時候會遇到很多應用程序中遇到的問題。在這一部分,關注學習方法論及理解每一個程序的邏輯。記住,編程中邏輯流是非常重要的。一個語句可能語法上正確但邏輯上卻是錯誤的。掌握了每一個應用程序的來龍去脈,會讓你在寫自己程序的時候更加自信。不要只是讀,要嘗試每個程序,修改并試驗它。它會幫助你掌握在課程中學習過的內容,進而解釋程序的不同行為。利用這些知識完成教師布置的編程作業。 對于教師作為一學期課程,本書的目的是為學生在后續課程中掌握高級編程奠定基礎,例如C編程中帶有C++的介紹,推薦你按照順序講完所有的內容。但是,按照不同的順序講解本書也是可以的。例如,課程3.2(單個字符數據)可以在第7章的課程前講述。同時,如果需要的話,課程8.7(生成頭文件)、課程8.8(使用多個源文件及存儲類別)、類似函數的宏和條件包含可以在第5章介紹。 你也可以將第7、8和9章的部分課程延后,時間允許再講解它們。例如,課程7.9(指針符號與數組符號)可以延后到指針的高級話題(第8章的附加材料,指向函數的指針和返回指針的函數,通過www.mheducation.asia/olc/cprogramming獲取)之前。 對于試圖建立編程基礎的一個學期課程,我們推薦你講解到課程7.8,再加上課程7.10、8.1、8.2、8.3、8.4和8.5。 對于給學生一般的編程體驗的短的課程,如果只講解前6章,學生也會寫出有價值且復雜的C程序。 本書提供了豐富的練習,課程部分后有判斷題和簡答題。學生應該獨立完成這些練習。課程后的一些簡單程序可以留作作業。一個星期的時間學生足可以完成一個程序。 應用程序部分后面的修改練習可以用于實驗課。學生應該在實驗之前學習相關的應用程序。實驗中,可以指導學生完成修改練習。一些練習比較容易,而另外一些很難,難的可以留作家庭作業。 大部分章末是應用練習。它們是本書中最有挑戰性的練習,所以最適合留作家庭作業。根據不同的難度,需要2~4周的時間來完成它們。 另外,本書可以用作ANSI C的參考書,參考表格分散在本書正文中。 教師輔助材料教師可在網站www.mheducation.asia/olc/cprogramming獲得以下補充材料。 解答手冊教學課件測試庫附加練習附加閱讀材料致 謝C Programming: a Q & A Approach感謝McGraw-Hill出版社的Eric Munson和Holly Stark。感謝他們對本書的興趣、支持、鼓勵以及有見地的建議。與他們一起工作非常愉快。感謝Byron Gottfried(BEST系列的編輯),感謝他的支持和寶貴的批評,以及McGraw-Hill的Alisa Watson和她的產品團隊,使得本書版式優美。 我們有一些非常有想法的評論家。University of Houston的Betty Barr;University of Texas的Raymond Bell;Fayetteville State University的Tat W. Chan;Texas A&M University的Bart Childs;University of Minnesota的Chris J. Dovolis;Illinois State University的Janet Hartman;New Mexico State University的Elden W. Heiden;Purdue University的Elias Houstis;University of Minnesota的Joseph Konstan;University of Maryland的Jandelyn Plane;還有 WPI的Matthew Ward,他們都給出了非常有幫助的建議,感謝他們的貢獻。 我們的計算機生涯開始于University of Michigan和 U. C. Berkeley. 感謝J. M. Duncan, John Lysmer和Raymond Canale教授(我們第一年計算機課程的指導老師),他們鼓勵我們解決一些復雜的問題,而由此帶來的成就感和自信促使我們寫這本書。 感謝Suzanne Lacasse 和 Kaare Hoeg,他們分別為Norwegian Geotechnical Institute的主管和前主管。他們對我們的自信以及在開發地理應用程序時給予的資助,延展了計算機技術背景,為進一步開發程序所需要的技能打下了堅實的基礎。感謝Hui Xian Liu(Institute of Mechanical Engineering中國哈爾濱地區的前主管), 感謝他對H.H. Tan不斷的支持、指導和鼓勵。 最后要感謝我們的家庭。T.B. D’Orazio的妻子Elizabeth雖然自己也很忙,但還是抽出時間鼓勵和支持我們。正是有了她,辛苦的工作才有了樂趣。感謝 H.H. Tan的妻子Wei Huang, 她一直是一個熱心、含蓄、聰明的女人。感謝 H.H. Tan的女兒Sijing Tan,前四章的大部分圖都是她繪制的。 H.H. TanT.B. D’Orazio感謝McGraw-Hill的Gerald Bok和Chris Cheung。Gerald是這個項目的主要推動人,他處理了大量瑣碎的事物,使得我們可以專注于本書的內容。Chris負責溝通協作,也提供了很多幫助。也感謝McGraw-Hill的Maureen Tan的大力支持。 S.H. Or要感謝香港中文大學的John Lui教授在擔任計算機科學和工程系主任時給予的支持。同時也感謝自己的妻子Pui-yee Lau,感謝她對孩子的細心照顧,使得自己可以專心于本書的編寫。 Marian Choy要感謝Tim Lambert(在University of New South Wales她最受歡迎的講師)讓自己看到了編程的樂趣和創造性。也要感謝Horace Ip教授在香港城市大學給了她第一個教學的職位。同時也感謝香港大學工學院的W.C. Chew和George L. Tham教授,他們提供了免費的平臺使自己可以探索和實驗各種教學方式。最后,感謝所有學習過她的編程課的學生,感謝她的家庭、小組成員、朋友和同事,感謝他們一如既往的支持,以及對自己“固執地”追求高水平教學質量的包容。 S.H. OrMarian M.Y. Choy
出版者的話
譯者序
前言
致謝
第1章 編程基礎 1
課程1.1 編程語言 1
1.1.1 匯編語言 1
1.1.2 高級語言 1
課程1.2 軟件工程 3
1.2.1 自頂向下模塊化設計 3
課程1.3 C語言、ANSI C和C編譯器 5
1.3.1 C和ANSI C 5
1.3.2 程序開發 5
課程1.4 利用位表示字符、符號、整型數、實型數、地址和指令 7
1.4.1 字符和符號 7
1.4.2 整型數 8
1.4.3 實型數 9
1.4.4 十六進制和八進制表示 9
課程1.5 關于本書及如何充分利用本書 10
1.5.1 課程 10
1.5.2 應用程序 11
課程1.6 基本結構 12
課程1.7 格式化輸出 16
課程1.8 其他轉義字符 18
課程1.9 基本調試 20
本章回顧 22
第2章 變量、算術表達式和輸入輸出 24
課程2.1 變量:命名、聲明、賦值和打印值 24
課程2.2 算術運算符和表達式 30
課程2.3 從鍵盤輸入數據 33
課程2.4 常量宏及打印變量值的進一步討論 37
課程2.5 混合類型的運算、復合賦值、運算符優先級和類型轉換 43
本章回顧 52
第3章 C語言基礎:數學函數和字符文件輸入輸出 53
課程3.1 數學庫函數 53
課程3.2 單個字符數據 57
課程3.3 從文件讀入數據 67
課程3.4 輸出到文件 72
應用程序3.1 面積計算——復合運算符和程序開發 74
應用練習 77
本章回顧 79
第4章 初級決策和循環 80
課程4.1 if 控制結構和關系表達式 80
課程4.2 簡單if-else控制結構 84
課程4.3 嵌套if-else控制結構 87
課程4.4 邏輯表達式 90
課程4.5 邏輯運算符的優先級 92
課程4.6 switch和if-else-if控制結構 96
課程4.7 while 循環(1) 102
課程4.8 while循環(2) 105
課程4.9 do-while循環 107
課程4.10 簡單for循環 109
課程4.11 嵌套for循環 112
應用程序4.1 梁交叉——if-else控制結構 116
應用程序4.2 面積計算——for循環 118
應用程序4.3 溫度單位轉換——for循環 120
應用程序4.4 溫度單位轉換——循環和if-else控制結構 121
應用程序4.5 仿真 123
應用程序4.6 工程經濟學——嵌套for循環 124
應用程序4.7 解二次方程——if-else控制結構(數值方法例子) 126
應用練習 128
本章回顧 131
第5章 函數 132
課程5.1 不返回值的函數 134
課程5.2 返回一個值的函數 142
課程5.3 作用域和傳值給函數的機制 146
課程5.4 返回多個值的函數 151
課程5.5 從函數返回多個值的
機制——地址和指針變量 153
應用程序5.1 使用帶有復雜循環的函數處理網格(邏輯例子) 159
應用程序5.2 模塊化程序設計:平行四邊形面積和平行六面體體積(數值方法例子) 164
應用練習 167
本章回顧 172
第6章 數值數組 173
課程6.1 一維數組和打印數組元素介紹 174
課程6.2 數組初始化 178
課程6.3 基本數組輸入輸出 181
課程6.4 多維數組 185
課程6.5 函數和數組 192
課程6.6 冒泡排序和最大交換排序 197
應用程序6.1 將16個1位加法器組成1個16位加法器 202
應用程序6.2 浪高的平均值和中位數(數值方法例子) 205
應用程序6.3 矩陣–向量乘法(數值方法例子) 209
應用程序6.4 搜索和文件壓縮 212
應用練習 215
本章回顧 219
第7章 字符串和指針 220
課程7.1 聲明、初始化和輸出字符串及理解內存布局 222
課程7.2 確定字符串和字符信息及使用printf 229
課程7.3 二維字符數組 234
課程7.4 從鍵盤和文件讀入字符串 238
課程7.5 指針變量與數組變量 245
課程7.6 在聲明中初始化 251
課程7.7 將字符串傳入用戶自定義函數 256
課程7.8 標準字符串函數 261
課程7.9 指針符號與數組符號 272
課程7.10 動態內存分配 279
應用程序7.1 管流速、檢查輸入數據及模塊化設計 285
應用程序7.2 地震軼事報告分析、字符串操作和動態內存分配 294
應用練習 305
本章回顧 308
第8章 結構和大型程序設計 309
課程8.1 結構 310
課程8.2 結構成員 316
課程8.3 指向結構的指針 318
課程8.4 結構和函數 321
課程8.5 結構數組 322
課程8.6 帶一個遞歸調用的函數 324
課程8.7 生成頭文件 329
課程8.8 使用多個源文件及存儲類別 331
課程8.9 位操作 334
應用程序8.1 排序——快速排序算法 342
本章回顧 350
第9章 C++介紹 351
課程9.1 C++注釋和基本輸入輸出流 351
課程9.2 格式操縱符及格式化輸出 354
課程9.3 函數重載 357
課程9.4 默認函數參數 360
課程9.5 內聯函數和變量聲明的位置 363
課程9.6 C++類和只有數據成員的對象 365
課程9.7 帶有數據和函數成員的類及封裝 369
課程9.8 構造函數和析構函數 375
課程9.9 繼承 379
應用程序9.1 電子電路 385
應用練習 389
附錄A ASCII碼 391
附錄B ASCII碼描述 392