白小軍,盧穎
(西安工業大學 計算機科學與工程學院,西安 710021)
計算機程序設計是高校理工科專業普遍開設的一門基礎課,目標是引導學生理解編程的思想和方法,并掌握一門語言工具以編程解決實際問題。近幾年來,隨著計算思維理念的發展,用計算學科的方法和工具來解決各專業領域的實際問題已成為一種趨勢,程序設計課程的重要性越來越凸顯出來。
然而在實際教學中,要實現課程的目標卻并非易事。首先,要學好該課程,學生需要投入大量的精力去編寫和調試程序,很多時候學生會對繁瑣的語法規則望而生畏,并因為程序無法運行而對編程失去信心;其次,編程的過程是一個邏輯思維的過程,而很多學生在剛入校時邏輯思維能力還有所欠缺,需要一個循序漸進的培養過程;另外,程序設計課程中通常使用流程圖來表達算法邏輯,但這種方式驗證性差,難以看到執行結果,無法驗證算法的正確性。
近年來出現了很多可視化編程工具,最典型的有Scratch、Blockly、Snap等。在程序設計課程中引入可視化編程,可以有效解決上面提出的問題。首先,計算思維的核心是思想方法而不是繁瑣的語法,使用可視化工具可以簡化編程,使學生注意力集中到程序邏輯上而不是語法規則上,有助于克服畏難情緒;其次,可視化編程能夠將程序邏輯清晰地展現出來,編程的過程就是邏輯思維鍛煉的過程;最后,使用可視化工具建模,設計好算法后能夠立刻跟蹤算法的執行過程并看到結果,方便驗證算法。
課程教學中,可在三個層面使用可視化編程:第一是算法層面,使用可視化程序代替流程圖,直觀地介紹常用算法的邏輯,并立刻進行驗證;第二是在編碼層面,結合編程語言的語法規則、控制結構等,將可視化程序轉化為相應語言的代碼,幫助學生實現從算法邏輯到程序代碼的轉換;第三是在模塊化層面,采用自定義積木的方式創建程序模塊,幫助學生理解模塊化設計的思想。
算法是程序的靈魂,也是培養學生計算思維、邏輯思維的根本。在課程開始階段,使用最簡單、有趣的工具展示算法設計,容易引起學生興趣。筆者在實踐中首先使用Scratch,其既提供基于網頁的在線版本,也提供離線安裝版本。該系統面向的目標首先是中小學生,設計的卡通形象和舞臺效果很吸引人,對大學新生也有足夠的吸引力。
在算法設計中,針對順序、選擇、循環及混合的處理邏輯,分別選取典型案例,用Scratch 積木可視化呈現,能起到良好的演示效果。
在順序結構部分,選用雞兔同籠問題,讓學生理解從問題到程序的轉換過程,“輸入—處理—輸出”的程序流程,以及變量、表達式等基本概念,如圖1 所示。在選擇結構部分,采用“輸入3 個數并輸出最大值”的示例,說明算法的流程結構,并以“if”及“if-else”等基本結構塊來實現算法,如圖2 所示。

圖1 雞兔同籠問題的算法

圖2 求3 個數最大值的算法


圖3 從1 累加到100 的算法

圖4 求π 值的算法
為幫助學生理解數組這一基本數據結構,設計“輸出Fibonacci 數列的前20 項”的示例,如圖5(a)所示,在循環結構中,演示了Fibonacci 數列的生成過程,同時,舞臺上的變量和數列顯示如圖5(b)所示,能夠直觀地看到數組數據的組織及訪問方式。

圖5 生成Fibonacci 數列的算法
可以看出,采用可視化工具代替流程圖來描述算法,不但簡單、直觀,而且能夠立刻執行、驗證,利于學生理解算法邏輯和數據組織方式。
可視化程序的構造塊和高級語言的語句都是對計算機指令執行過程的高級抽象,兩者間具有相似性,只要學習了高級語言的語法規則和控制結構,就能很容易地將可視化程序轉化為高級語言代碼。以圖2 和圖4 為例,轉化為C 語言代碼分別如圖6 和圖7 所示。

圖6 輸入3 個數求最大值的代碼

圖7 根據公式求π 值的代碼
這種編程訓練在課堂教學中可以分兩步來實施,首先由教師主導,提出問題并設計可視化程序,引導學生理解算法邏輯;然后由學生動手,根據語法規則和程序結構,將可視化程序轉化為具體的語言代碼,完成從算法邏輯到高級語言程序的轉換。在設計可視化程序的過程中,可以引出變量及其存儲方式、運算符、表達式、流程控制和輸入輸出等概念,而這些概念在轉化程序時又可以方便地映射到高級語言的語法規則中。通過這一分解,將原來復雜的編程問題轉化為2 個相對簡單的步驟來完成,利于學生克服畏難情緒,也利于抓住編程的要點。
模塊化編程是程序設計課程的核心內容之一,高級語言中一般都通過函數來實現模塊化設計。Scratch 難以模擬高級語言中函數的功能,所以需要一套更加強大的可視化編程工具。筆者采用功能更加強大的可視化編程工具Snap,其提供基于Web 的編程環境,可視化程序可以保存在客戶端或云端;且支持常用的數據類型,完全支持模塊化開發,甚至允許創建新的控制結構,能夠完美地用于程序設計課程的教學。
Snap 采用自定義積木的方式制作程序模塊,例如,為求一組數據中的最大值,設計如圖8 和圖9 所示的程序。其中,第一個積木塊定義了函數的原型,函數名為getArrMax,需要傳遞進來一個數組s 作為參數,并返回一個數據m 作為最大值;中間部分定義了求最大值的算法,首先假定數組第一項為最大值,存入變量m,其后循環遍歷所有的數組元素,當發現某項值大于m 時,用其替換m 值,這樣循環結束時,m 中存放的就是數組元素的最大值;最后一個積木塊向主調程序返回數據,相當于高級語言中的return 語句。主調程序如圖9 所示,其核心部分(第三個積木塊)調用了自定義的函數求數組中的最大值。

圖8 求最大值的自定義模塊

圖9 求數組最大值的主程序


圖10 求組合數的自定義模塊

圖11 求階乘的自定義模塊
遞歸是計算學科中一種獨特的思想方法,即:一個函數可以直接或間接地調用自身,前提是必須滿足三個基本條件:(1)有一套遞推公式;(2)每次遞推后函數的運算規模都會減小;(3)當遞推到一定條件時找到出口。例如,對求階乘的函數進行改造,設計如下的遞推公式,就可以采用遞歸算法來實現。改造后的求階乘函數如圖12 所示。

圖12 求階乘的遞歸算法

通過以上示例,可以直觀地展示模塊化設計中的核心概念和思想方法。
在該課程的實踐教學中發現,很多學生的編程能力始終跟不上課程節奏,直到課程結束,也難以獨立完成較復雜的程序。究其原因,一是程序的邏輯較為抽象,學生沒有理解程序的執行過程,難以正確地設計程序結構;二是高級語言的語法規則較為繁瑣,學生將大量精力都浪費在了處理語法錯誤上。而當這兩個問題交織在一起的時候,調試程序的難度就急劇上升,學生很難定位錯誤到底出在哪里,所以每次實踐課程的收獲都很有限,很多同學僅限于將教材上的代碼搬進計算機,使之運行起來,而獨立編寫和調試代碼的能力明顯不足。
引入可視化編程,將復雜的問題分解為兩步完成。第一步,根據實踐任務進行可視化設計,深入理解程序邏輯,并且直觀地觀察程序的運行過程,相互對照,熟練掌握程序結構;第二步,將可視化程序轉化為高級語言代碼,并上機調試。這樣分解的好處在于解耦了程序邏輯錯誤與語法錯誤之間的關系,更容易發現和解決問題。
以選擇排序算法為例,在課堂講解時幫助學生理清算法思路,并獨立完成可視化程序設計,如圖13 所示,該模塊在數組元素值互換的代碼塊中加入1 秒延時,運行程序時觀察數組變量,可以清楚地看到每一輪迭代中元素的互換和移動,便于理解算法邏輯。當可視化程序調試成功后,可以確保算法邏輯沒有問題,這時進入第二步,轉化高級語言代碼,由于可視化構造塊與高級語言語句塊之間很大程度上有對應關系,所以這種轉化相對來說難度不大。基于以上步驟,學生對程序的理解更加深刻,也更容易編寫和調試程序。

圖13 選擇排序的可視化算法
筆者將可視化編程引入本科生計算機程序設計課程的教學,從算法邏輯、代碼轉換和模塊化設計三個方面展開研究,在課堂教學和實踐教學中進行了嘗試。從教學效果來看,學生的學習興趣得到了提高,不再畏懼編寫代碼,邏輯思維得到了鍛煉,能夠熟練地描述算法邏輯并進行驗證,閱讀程序和編寫程序的能力得到了明顯改進,對程序的理解上了一個臺階。實踐證明,引入可視化編程,能夠有效改進課堂教學和實踐教學的效果。