第2版前言
本書是在《C 語言程序設計( MOOC版)》的基礎上進一步總結愛課程網“中國大學MOOC”(http://www.icourse163.org/)的網絡教學實踐修訂而成。依據本教材開設的“C 語言程序設計”MOOC(慕課)課程已開設四個學期,累計選課人數超過十萬人。
MOOC學員能夠積極參與課堂討論,提出各種問題,並對如何開展C 語言程序設計教學提出了很多寶貴的意見和建議。這裡分享幾個MOOC課堂的精華貼。
【空空mooc369】:這門課是學軟件的,為什麼第1章很多內容是關於硬件的呀?
【教師回復】:初學者學習程序設計,首先應樹立以下兩個觀念。
(1) 程序員向計算機硬件下達指令,然後由硬件執行指令。程序員應首先了解硬件的基本結構和工作原理,這樣纔能知道如何向硬件下達指令。
(2) 程序是一組下達給計算機硬件的指令序列(或稱為語句序列)。僅從語法角度去理解,語句是抽像的。初學者要學會從有形的硬件去理解抽像的語句和語法。
程序設計課程隻在一開始簡單介紹一下硬件,後續章節在講解C 語法時會提及內存或CPU等硬件。
【luckymooc360】:C 語言為什麼提出引用和指針的概念?
【教師回復】:程序員通過定義變量來申請內存,再用變量名訪問所分配的。大型程序需要多個程序員協作開發,共同完成。如果其他程序員想訪問上述變量的,例如讀取其中的數據,可以嗎?答案是肯定的,可以,但隻能通過引用或指針來訪問(即間接訪問)。
【小二上盤ID】:老師,我們學校先學C語言,然後學的是C#和Java。怎樣纔能學好程序設計?以後從事工作用Java好,還是C/C 好?
【教師回復】:如何學習程序設計,這是很多初學者經常提出的問題。經過一段時間的學習,很多同學會產生新的困惑。例如,理論知識看了好幾遍了,但是怎樣提高編程能力?自己對MOOC課程的學習效果很滿意,下一步該做什麼?程序設計的學習過程是什麼樣的,終能學到什麼程度?針對這些問題我談一下個人體會,供同學們參考。
學習程序設計大致可以分為三個階段:初級、中級和高級。
(1)初級。初級階段的目標是學習程序設計原理,其中包括計算機硬件基本結構及其工作原理,程序如何管理內存來存儲數據(例如變量的定義與訪問,數據類型,引用與指針等)、程序如何控制CPU來處理數據(例如各種不同的運算符,或通過控制語句來控制指令的執行順序)等。程序設計原理還要學習如何設計大型、復雜的程序,這就需要學習程序設計方法。程序設計方法有兩種,分別是結構化程序設計和面向對像程序設計。初級階段學習結束後,同學們可以參加計算機等級考試(二級)或各種程序設計大賽等活動,並在應試過程中進一步提高自己的水平。
(2)中級。中級階段的目標是學習程序應用開發(學會就能有好工作了哦)。程序應用開發需要基於別人的程序來開發,從零開始是不可能的。結構化程序設計方法規定:其他人給你函數庫,你要會調用別人的函數。面向對像程序設計方法規定:其他人給你類庫,你要知道如何使用別人的類庫。因此我們在學習應用開發之前必須要掌握結構化程序設計方法或面向對像程序設計方法。目前面向對像程序設計是主流,已經很少有人繼續給程序員提供函數庫了,所提供的都是類庫。掌握了面向對像程序設計方法,你隻要拿到微軟公司提供的MFC類庫(隨Visual C 6.0或Visual Studio提供),就可以用C 語言開發Windows圖形界面的程序(或者你拿到蘋果公司的類庫、谷歌公司的類庫,就可以使用這些類庫開發iPhone或Android繫統的App了)。不同的操作繫統是由不同廠家開發的,它們對計算機語言的支持程度有所不同。例如,Windows操作繫統是由微軟開發的,開發Windows軟件主要使用C 和C#語言; MacOS/iOS操作繫統是由蘋果公司開發的,開發MacOS/iOS軟件主要使用Objective-C(C 的變種);Android操作繫統(從Linux演變而來)由谷歌公司主導,開發Android軟件主要使用Java語言。可以看出,程序應用開發可能會用到不同的計算機語言,但程序設計原理是共同的。
(3) 高級。高級階段的目標是提高自己的理論水平,不光要知其然,還要知其所以然。計算機專業的同學需要先學習程序設計原理,然後再學習計算機組成原理、數據結構、操作繫統、編譯原理、數據庫原理、計算機網絡、計算機圖形學、數字圖像處理、算法設計、離散數學和人工智能等課程。在學習完這些專業課程之後,你的理論水平會得到很大提高,將會成為一名真正的高手。
【LingDash】:老師,總地來說講得挺好的,但是我有些想法。比如在講類的繼承與派生時,應先讓學生體會到,每個類都從底層開發十分麻煩,那麼怎麼解決呢?這時引出“類的繼承與派生”,將用與不用“類的繼承與派生”進行比較,這樣的學習會更加符合人的認知規律。
【教師回復】:有道理,接受你的建議,謝謝!
【cc76965】很高興能夠遇到這門公開課。這門公開課的條理十分清晰,讓我對C 的語法有了一個清晰的脈絡。我是一名計算機專業的學生,已經學了數據結構,但是缺少開發項目的經驗。不知道如何去尋找開發項目,也不知道如何下手,希望老師能夠給我一些建議。
【網友Crazy峰少回復】:下面這個網站裡有大量的編程題目可以做:https://www.patest.cn/。
這一版就是在總結廣大MOOC學員所提出的難點、問題和建議的基礎上對上一版所做的修訂。重點完善了結構化程序設計和面向對像程序設計這兩種程序設計方法的內容,使之更加繫統化。
在此謹向中國大學MOOC和所有提出寶貴建議的MOOC學員們表示感謝!
作者
2017年3月於北京
前言
1. 關於MOOC
MOOC(Massive Open Online Course),即大規模開放在線課程,中文譯為“慕課”,是近幾年興起的一種基於互聯網的新型教學模式。2012年被稱為“M年”。MOOC教學模式實現了兩個轉變,即由以教師為中心向以學習者為中心轉變,學習者則由被動學習向主動學習轉變。與普通網絡教學視頻所不同的是,MOOC實現了從授課到習題、討論、答疑、測驗,直到終學習評價等環節的完整教學過程。與傳統課堂授課不同的是,開設MOOC課程需重新梳理和組織知識點,並分別提供適合線上使用的練習題以及線下使用的討論或實驗題。
可以將線上MOOC與線下課堂這兩種教學模式結合起來。線上MOOC就是先由學生自主完成知識學習,例如觀看視頻、做線上習題等。線下課堂則是由教師組織課堂討論、實驗、測驗,或講解重點疑難問題。“線上MOOC,線下課堂”是對現有“課上聽課,課下作業”教學模式的翻轉。雖然MOOC教學模式尚處於起步試驗階段,但大多數網絡學習者十分喜歡MOOC。目前已湧現出很多知名的MOOC網站,例如國外的Coursera、Udacity和Edx,國內的中國大學MOOC、學堂在線和雨虹學網等。中國農業大學也正在基於雨虹學網積極開展校內課堂教學改革方面的嘗試與探索。
學習C 語言程序設計需要邊閱讀、邊思考、邊消化吸收。雖然有了大量的網上資源,但紙質教材仍是初學者線下學習的方式,這也是作者編寫出版本書的目的。
2. 本書特色
1)適用於MOOC在線教育課程
本書按應用需求來梳理和組織C 語言的知識點,其中包括結構化程序設計方法和面向對像程序設計方法。內容編排由易到難,循序漸進。每個小節都設計了適合在線評判的單選練習題,每章則設計了適合課堂討論的程序閱讀題、改錯題和編程題。
2)采用案例教學
每個知識點都從精心設計的任務需求開始導入,然後提出對應的實現方法,後繫統地闡述其語法細則,既保證了知識體繫的完整性,又能讓讀者直觀理解抽像的概念和原理。
3)創新教學方法
本書從三個方面對C 語言教學進行了探索。一是強化初學者對“程序由計算機硬件執行”這一基本概念的認知,從有形的硬件來理解相對抽像的程序,這樣各種語法概念就不再那麼抽像了;二是明確提出程序設計過程中存在不同的程序員角色,並充分利用角色來引導讀者理解語法的應用語境;三是明確提出必須從代碼分類管理、數據類型、歸納抽像和代碼重用等多個維度纔能準確理解面向對像程序設計方法。教學實踐表明,上述教學方法可降低學習難度。
3. 內容摘要
本書內容按章節順序可分為三部分,分別是程序設計基礎(第1~4章)、結構化程序設計方法(第5~6章)和面向對像程序設計方法(第7~10章)。
第1章 程序設計導論。從初學者對計算機已有的認知開始,將初學者逐步引導到計算機程序的世界。本章首先介紹計算機硬件、指令及機器語言、程序等基本概念,然後描述程序與計算機硬件、程序員、用戶之間的關繫,讓讀者在一開始就能明確程序員的職責,實現從用戶到程序員的角色轉換。本章要點:一是讓讀者從有形的硬件來理解相對抽像的軟件;二是讓讀者認識到計算機中的數據是有類型的,類型決定了數據在計算機中的存儲位數和存儲格式;三是讓讀者知道,學習程序設計和學習編程語言不是一回事。和C語言、Java語言相比,C 語言的知識體繫更加繫統、全面。本書選用C 語言作為程序設計初學者的入門語言。
第2章 數值計算。本章從簡單的數值計算問題開始,以案例教學的方式讓讀者領會程序設計中一些基礎的概念,其中包括程序中的變量和常量、表達式與運算符、數據的輸入和輸出等。後介紹了C 程序訪問內存的三種方式,它們分別是變量名、引用和指針。本章要點:一是讓讀者將程序中的數據與內存聯繫起來,這樣就很容易理解數據類型、引用和指針等初學者難以掌握的概念;二是讓讀者重點關注運算符的運算規則、優先級和結合性等語法細節;三是讓讀者初步體會到計算機語言與人類語言的不同之處,即計算機語言的語法規則非常嚴格,甚至到了機械的程度,稍有不慎就會出現語法錯誤。
第3章 算法與控制結構。本章講解程序中的算法及三種算法基本結構,並通過選擇結構和循環結構中的條件引出布爾類型。C 語言通過選擇語句來描述選擇結構算法,通過循環語句來描述循環結構算法。後通過案例簡單講解算法的設計與評價方法。本章要點:一是讓讀者了解絕大部分復雜算法都可以由三種基本的算法結構來完成;二是讓讀者掌握布爾類型的作用及其相關的運算符;三是讓讀者了解編程能力實際上是一個人計算思維能力的反映,閱讀程序和模仿編程是初學者培養計算思維能力的兩個重要途徑;四是讓讀者根據案例認真體會如何根據算法合理選用不同的控制語句。
第4章 數組與文字處理。本章學習如何在程序中存儲和處理大量數據。數組可以存儲大量具有相同類型的數據集合。計算機隻能存儲和處理數值數據,而文字處理程序所處理的對像是字符數據,為此,C 語言引入了字符類型。讀者需深入了解字符編碼和字符類型。文字處理必須使用數組,即字符型數組。本章後用一節的篇幅簡單介紹了中文處理及Unicode編碼。本章要點:一是讓讀者重點掌握數組定義及訪問的語法規則;二是讓讀者認識到計算機內部對數組的管理和訪問是通過指針(即內存地址)來實現的;三是讓讀者通過具體案例初步了解數組的常用處理算法。
經過前4章的學習,讀者已掌握了程序設計原理基礎部分的內容。那麼該如何編寫更大型的計算機程序呢?這就需要進一步學習程序設計原理的高級部分,即程序設計方法。程序設計方法的基本思想是:將大型程序中的數據和算法分解成程序零件,將不同零件的設計任務交由不同的程序員完成,這樣就能以團隊的形式來共同開發。更進一步,如果所分解出的程序零件在以前項目中曾經開發過,或者可以從市場上購買到,那麼就可以直接使用這些零件來組裝軟件,實現快速開發。使用已有的程序零件,實際上是重用其程序代碼,這就是程序設計中的代碼重用。從第5章開始,本書對程序設計方法進行繫統介紹。
第5章 結構化程序設計之一。本章學習如何將一個復雜的數據處理算法分解成多個簡單模塊,分而治之,這被稱為是結構化程序設計方法。C 語言支持結構化程序設計方法,以函數的語法形式來描述和組裝模塊,即函數的定義和調用。函數是結構化程序設計方法的基礎,它為代碼重用提供了有效的手段。函數之間需要共享數據纔能完成規定的數據處理任務。C 語言提供了集中管理和分散管理兩種不同的數據管理策略。本章要點:一是讀者要準確領會結構化程序設計的思想內涵,並熟練掌握C 語言中函數相關的語法知識;二是讓讀者深入計算機內部,了解程序執行時其代碼和變量在內存中的存儲原理,這樣可以更容易理解變量作用域和生存期等抽像的概念;三是讀者要準確把握函數間傳遞數據的三種方式;四是讀者要分別站在兩種不同的程序員角度,即定義函數的程序員和調用函數的程序員,纔能更容易地理解函數相關的各種語法知識。
第6章 結構化程序設計之二。本章學習如何以多文件結構的形式來組織和管理源代碼,並介紹幾種常用的編譯預處理指令;然後再介紹幾種特殊形式的函數,其中包括帶默認形參值的函數、重載函數、內聯函數、帶形參和返回值的主函數以及遞歸函數等。本章還會介紹與C語言相關的繫統函數和自定義數據類型。本章後以微軟公司開發的Win32 API函數庫為例介紹如何開發一個Windows圖形用戶界面程序,並對結構化程序設計方法進行簡單的回顧和總結。本章要點:一是學習掌握與多文件結構相關的語法知識,其中包括外部函數和全局變量的聲明、頭文件等;二是重點掌握帶默認形參值的函數、重載函數和內聯函數這三種常用的特殊函數形式;三是牢固樹立重用代碼的思想,學會通過調用他人編寫的函數來提高開發效率。
第7章 面向對像程序設計之一。面向對像程序設計方法將程序中素素根據其內在關聯關繫進行分類管理,這就形成了“類”的概念。分類可以更好地管理。類相當於是一種自定義的數據類型,用類所定義的變量稱為“對像”。本章通過具體案例演示了結構化程序設計是如何演變到面向對像程序設計的,然後再繫統地介紹面向對像程序設計方法。本章內容包括類的定義、對像的定義與訪問、對像的構造與析構、類中的常成員與靜態成員以及等。本章要點:一是讀者必須從代碼分類管理、數據類型、歸納抽像和代碼重用等多個維度纔能準確理解類與對像的概念;二是讀者需認真學習類與對像編程的具體語法規則;三是深入領會面向對像程序設計通過設置訪問權限來實現類封裝的基本原理;四是深入了解對像的構造與析構過程,程序員通過編寫構造與析構函數來參與對像的構造與析構過程;五是讀者要懂得從兩個不同的角度,即定義類的程序員和使用類定義對像的程序員,纔能更容易地理解類與對像相關的各種語法知識。
第8章 面向對像程序設計之二。重用類代碼有三種方式,分別是用類定義對像、類的組合和類的繼承。本章講解類的組合與繼承。程序員可以基於已有的零件類來定義新的整體類,這就是類的組合。程序員可以繼承已有的基類來定義新的派生類,這就是類的繼承與派生。利用派生類和基類之間的特殊關繫可以進一步提高程序代碼的可重用性,這就是面向對像程序設計中的對像替換與多態技術。本章將具體講解與多態相關的運算符重載、虛函數和抽像類等概念。後本章將簡單討論一下類的多繼承。本章要點:一是讓讀者學會使用組合和繼承的方法來定義新類,這樣可以提高類代碼的開發效率;二是讀者應理解,類在組合或繼承時可以進行二次封裝;三是從提高程序代碼重用性的角度可以更容易地理解對像多態性;四是多繼承會導致語法陷阱,新的面向對像程序設計語言(例如Java和C#)已不再支持類的多繼承,而隻支持接口的多繼承,讀者隻需要了解多繼承的基本原理即可。
第9章 流類庫與文件I/O。C語言通過輸入/輸出函數(例如scanf和printf)實現了數據的輸入和輸出。C 語言則是通過輸入/輸出流類為程序員提供了輸入/輸出的功能。這些輸入/輸出流類都是從類ios派生出來的,組成了一個以ios為基類的類族,這個類族被稱為C 語言的流類庫。本章將介紹流類庫中三組不同功能的輸入/輸出流類,它們分別是通用輸入/輸出流類、文件輸入/輸出流類和字符串輸入/輸出流類。本章要點:一是讀者應理解之前所用的cin、cout指令實際上分別是通用輸入/輸出流類的對像;二是通過本章學習,讀者可以從側面了解全球的C 程序員是如何來設計和編寫類的,這樣可以幫助讀者進一步深入體會前面所學習的各種面向對像程序設計知識;三是重點學習如何進行文件讀寫操作,大部分程序都需要使用文件來保存數據。
第10章 C 標準庫。C 語言全盤繼承了C語言的標準C庫,另外又增加了一些新的庫。新庫中包含一些新增的繫統函數,但更多的是為面向對像程序設計方法所提供的繫統類庫,這些新庫被統稱為C 標準庫。為了更好地凝練源代碼,C 語言引入了模板技術,其中包括函數模板和類模板。模板技術是一種代碼重用技術,C 標準庫在編寫時就采用了模板技術,因此標準庫能以較少的代碼量來提供很強大的功能。本章內容重點介紹模板技術、C 語言的異常處理機制以及C 標準庫所提供的數據集合存儲及處理功能。本章後以微軟公司開發的MFC類庫為例介紹如何開發一個Windows圖形用戶界面程序。本章要點:一是讓讀者了解如何使用模板技術來提高函數和類代碼的可重用性;二是重點學習C 語言的異常處理機制;三是初步掌握如何使用C 標準庫中的向量類、列表類、集合類和映射類來存儲和處理數據集合。
學習完C 面向對像程序設計之後,程序員在拿到一個具體的程序設計任務時,首先應當考慮有哪些現成的類庫可以使用。使用現成的類庫開發程序,開發周期將大大縮短。基於已有的類庫開發程序,相當於是用別人已經做好的零件來組裝產品。程序的應用開發,通常就是用已有的程序零件來組裝自己的軟件產品。隻要掌握了面向對像程序設計方法和C 語言,相信每位讀者都能夠借助各種第三方類庫,發揮出無限的開發潛能。
4. 使用建議
凡希望開設C 語言程序設計在線教育課程的教師,可將本書作為授課教材。聯繫作者可免費獲得配套教學課件和視頻。參加在線課程學習的學生可將本書作為線下閱讀教材。
如將本書作為課堂教學用書,則建議講課學時和實驗學時各為32學時,合計64學時。每學時50分鐘。作者本人按如下方式安排講課學時:第1、3、4、9、10章各2學時,第2、5、6、7章各4學時,第8章6學時。
聯繫作者:kandaohong@cau.edu.cn
5. 致謝
作者編寫本書的想法源於中國農業大學“雨虹學網:面向主動學習的教學雲平臺建設”項目。在參與相關繫統開發和教學實踐的過程中,作者積累了一些MOOC在線課程教學的經驗。
本書編寫過程中,得到了中國農業大學信電學院高萬林院長的熱情鼓勵和大力支持。本書部分素材來自於雨虹學網的教學實踐活動,這得益於張曉東教授、孫瑞志教授等領導的關心和指導。另外,本書在編寫過程中還得到了鄭立華、呂春利、冀榮華、劉雲玲、陳瑛、周緒宏、胡慧、段晶潔、李鑫、李靜等同事和同學的熱心幫助。在此一並致以衷心的感謝!
後,感謝家人對我的理解和支持。
作者
2015年9月於北京