董巍
(湖北文理學院計算機工程學院,襄陽 441053)
C 語言廣泛用于系統軟件、單片機應用的開發之中;它是大學計算機類專業程序設計課程的首選教學語言;在TIOBE 網站每月公布的計算機編程語言排行榜上,其一直占駐第一或第二名的位置[1]。這些,充分體現了C 語言的生命力強和應用范圍廣的特點。
C 語言作為計算機類專業教學的第一門編程語言,教學目的主要有兩點:一是對程序設計基本概念、原理、方法的了解、掌握和運用,二是對程序編碼與程序調試能力的訓練和培養。即承擔著編程啟蒙和入門、進而為學習其他編程語言、后續專業課程提供專業術語和編程技能的服務作用。由于其基礎性和重要性,針對C語言程序設計課程的教學內容、教學方法和教學手段的研究層出不窮、方興未艾。在中國知網,以“C 語言”、“教學”為主題搜索到的5000 多條文獻中,多是關于教學方法、教學模式的研究,而針對課程知識點的相互關系和深度應用的研究則比較少。因此,本文從C 語言的幾個重要知識點的應用出發,結合教學規律和教學方法展開探討,幫助提高該課程知識的教、學、用。
學習具有四個階段:識記、理解、意識、悟性。即是我們常說的了解和記憶、理解和掌握、熟悉和應用、拓展和創新,它們呈現逐級提升的狀態。
識記是學習任何知識的第一階段,是高樓大廈的基石,學生也會花費大量的時間進行知識的識記。
大量的事實表明學生對識記性知識掌握、直接運用的效果并不好。例如:講述了標識符的命名方法、特別是命名要遵循“見名知意”的原則之后,學生在給程序文件、文件夾命名時仍習慣于使用數字或漢字作為名稱,程序中變量的命名仍五花八門、晦澀難懂。
一些具有豐富教學經歷和經驗、對教學內容有深刻理解的教師,可以直接傳授給學生第二級的信息——理解。
C 語言是學生接觸的第一門程序設計語言,其包含的概念、原理、方法、技巧等呈現多繁雜的特點。因此,提出了“語法夠用、重在算法”的觀點,且踐行著“化繁為簡、循序漸進”的教學思想。例如:在講述scanf、printf 函數時,強調格式控制符的類別和個數必須與變量的類型和個數一致,以避免鍵盤輸入數據的非法而導致變量獲取值的錯誤、輸出時數據的存儲格式轉換而導致的亂碼;再例如:對“if(表達式)”,其標準的樣式是“if(exp!=0)”,由于C 語言的靈活性,常將其簡寫成了“if(exp)”;而對于“if(!exp)”的理解,可將其直接補充為“if(!exp!=0)”、再將兩側的“!”同時去掉、則演變成了“if(exp==0)”,這樣的推導、理解使得學生感覺到豁然開朗,既簡潔又直觀。
經歷了認知、理解、練習、思考、總結之后,真正做到融會貫通、形成意識,則學習已經進入到了一定的高度和境界,也就是培養出了計算思維。這不是老師所能直接完成的任務,即意識只能訓練、培養,不能傳授。通常,在講述循環結構、數組、函數時,一般會講解大量的、典型的例題,再配以大量的練習題,以此來鞏固基本概念、歸納基本方法、總結解題經驗和技巧、擴展應用范圍等,更重要的是實現數學思維向計算思維的逐步轉變和培養[2]。
珍貴的不是那些死記硬背的知識,而是創造知識的悟性。對大眾來說,主要是運用所學知識解決實際問題,即應用;對少數悟性高的人來說是創新。老師所能做的只能是啟發、誘發、激發、開發。應運而生的是在大學廣泛開展的創新創業教育、學業導師制等。
C 語言程序設計課程中存在大量的概念和專業術語,既需要嚴謹的書面語言對其進行定義、也需要通俗易懂的口頭語言對其進行講解;既需要理解其字面意思,更需深刻理解其內涵和外延。
例如,數組是“一批類型相同、名稱相同的元素組成的有限序列”,這句話體現出了數組的類型、名稱、容量、有序(值及其順序)等意思,因此,在編程時聲明和定義一個數組則分別需要緊抓其三、四要素[3];數組的應用則緊緊圍繞其四要素展開,特別是數組元素的值和實際元素個數,且數組實際元素的個數可能是動態增長的。重點練習的題目有求一個整數的所有因子、所有質因子,使用數組模擬集合的并較差補運算等。這些題目既包含了對概念的深刻理解、也包含了基本的算法。
再如,對函數首部“三要素”的理解、確定和使用,特別是函數的類型、最重要的是函數參數的個數和類型的確定,因為通過函數調用只能返回一個值,要想得到多個值就必須通過函數的參數來完成、且參數必須使用指針型參數[4],這是教學的重點和難點。
函數應用的目的在于程序結構化、模塊化和重用性。初學者可能更習慣于整個程序只有一個main 函數,這樣的話,略微復雜的程序則繁瑣冗長、結構不清晰、功能不明確,或者函數中包含有數據的輸入輸出,或者大量使用全局變量,或者所有函數都是空類型而沒有返回值……,這些都會降低程序的可讀性、結構化、模塊化、重用性等。解決辦法是采取“三步曲”的模式進行講授:主函數中只由三類語句構成,第一是輸入、第二計算、第三是輸出,第二中的計算自然而然必須使用自定義函數來實現,且需根據計算的復雜性進行再分解。經過一段時間的訓練逐步建立“三步曲”的思想,從而逐步建立函數思維。
再如,鏈表是C 語言學習的難點、也是重點,若對鏈表操作中幾個賦值語句能很好地理解,則能達到事半功倍的效果。假設有如下的賦值語句:

這些賦值語句,從物理上看、或者說從右向左看是賦值,是把一個地址值賦值給另一個指針變量或指針變量的指針域;從邏輯上看、或者說從左向右看是指向,是一個指針指向另一個結點;若賦值號左邊是某個變量的指針域則表示是鏈的連接[5]。這樣的理解將使得復雜的指針運算變得形象直觀。對這幾個賦值語句的正確理解、運用,將會對鏈表操作、更是對《數據結構與算法》課程的學習起到事半功倍的效果。
模運算是一個重要的運算符,其典型應用有:分離一個整數各數位上的數字,數學黑洞問題,判斷一個整數是否為素數,求一個整數的因子,輸出某年某月某日是星期幾,仿照電腦上日歷的樣式打印萬年歷,根據“三天打魚兩天曬網”的規則判斷漁夫某天該干啥[6],多個空瓶換汽水的問題,等等。
位運算在解決實際問題的應用中具有更大的實際意義。如位與運算,本意是對兩個整數的對應二進制進行與運算,從而得到一個新的整數;物理意義則是屏蔽或析出一個整數某個二進制位上的值。例如:判斷一個整數是奇數還是偶數,常使用的方法是模運算,而使用位與運算則顯得更為“高大上”;在根據幾句話判斷幾名嫌疑人究竟哪些是罪犯的推理題中,可以使用一個整數的幾個二進制位來代表幾名嫌疑人,即將嫌疑人的一組狀態映射到一個十進制整數的固定二進制位上[7],則是位運算的深度應用。
在C 語言程序設計的教學中,假設法、枚舉法、篩選法是常使用的方法和技巧。
例如:三個數求最大值、通過數組求最大值、進而推廣到通過一個循環同時求解一批數據中的最大值和最小值、最后拓展到選擇排序,“假設第一個數就是最值”這一思想體現得淋漓盡致;使用數組篩選出素數、約瑟夫問題、紅黑球的放置問題等等,既體現了篩選法的應用、又顯現了整數(或編號)與數組下標之間的映射[8]。
上面這些基礎性的題目,既有多個知識點的綜合應用、也呈現出了從簡單到復雜的遞進關系、更有問題的追根溯源(雛形)。因此,不論是教師、還是學生都需要不斷的分析、思考、總結、探索。
對于基礎型課程,在教學中運用最多的是案例式、遞進式、設問式教學等,還有翻轉課堂正不斷興起和大量運用。
深入研究課程內容,挖掘知識點之間的相互關系,創設更多更好的基礎性、綜合性、應用性的題目,因地制宜地運用多種教學方法和手段,因材施教地開展教學,把教學重心轉移到“五個突出”上,即突出理解基本概念、突出掌握基本技能、突出計算思維養成、突出核心知識點把握、突出編程能力訓練,從而推動本科院校教學水平和教學質量的不斷提高。