白小軍,盧穎
(西安工業(yè)大學(xué) 計(jì)算機(jī)科學(xué)與工程學(xué)院,西安 710021)
計(jì)算機(jī)程序設(shè)計(jì)是高校理工科專業(yè)普遍開設(shè)的一門基礎(chǔ)課,目標(biāo)是引導(dǎo)學(xué)生理解編程的思想和方法,并掌握一門語言工具以編程解決實(shí)際問題。近幾年來,隨著計(jì)算思維理念的發(fā)展,用計(jì)算學(xué)科的方法和工具來解決各專業(yè)領(lǐng)域的實(shí)際問題已成為一種趨勢(shì),程序設(shè)計(jì)課程的重要性越來越凸顯出來。
然而在實(shí)際教學(xué)中,要實(shí)現(xiàn)課程的目標(biāo)卻并非易事。首先,要學(xué)好該課程,學(xué)生需要投入大量的精力去編寫和調(diào)試程序,很多時(shí)候?qū)W生會(huì)對(duì)繁瑣的語法規(guī)則望而生畏,并因?yàn)槌绦驘o法運(yùn)行而對(duì)編程失去信心;其次,編程的過程是一個(gè)邏輯思維的過程,而很多學(xué)生在剛?cè)胄r(shí)邏輯思維能力還有所欠缺,需要一個(gè)循序漸進(jìn)的培養(yǎng)過程;另外,程序設(shè)計(jì)課程中通常使用流程圖來表達(dá)算法邏輯,但這種方式驗(yàn)證性差,難以看到執(zhí)行結(jié)果,無法驗(yàn)證算法的正確性。
近年來出現(xiàn)了很多可視化編程工具,最典型的有Scratch、Blockly、Snap等。在程序設(shè)計(jì)課程中引入可視化編程,可以有效解決上面提出的問題。首先,計(jì)算思維的核心是思想方法而不是繁瑣的語法,使用可視化工具可以簡(jiǎn)化編程,使學(xué)生注意力集中到程序邏輯上而不是語法規(guī)則上,有助于克服畏難情緒;其次,可視化編程能夠?qū)⒊绦蜻壿嬊逦卣宫F(xiàn)出來,編程的過程就是邏輯思維鍛煉的過程;最后,使用可視化工具建模,設(shè)計(jì)好算法后能夠立刻跟蹤算法的執(zhí)行過程并看到結(jié)果,方便驗(yàn)證算法。
課程教學(xué)中,可在三個(gè)層面使用可視化編程:第一是算法層面,使用可視化程序代替流程圖,直觀地介紹常用算法的邏輯,并立刻進(jìn)行驗(yàn)證;第二是在編碼層面,結(jié)合編程語言的語法規(guī)則、控制結(jié)構(gòu)等,將可視化程序轉(zhuǎn)化為相應(yīng)語言的代碼,幫助學(xué)生實(shí)現(xiàn)從算法邏輯到程序代碼的轉(zhuǎn)換;第三是在模塊化層面,采用自定義積木的方式創(chuàng)建程序模塊,幫助學(xué)生理解模塊化設(shè)計(jì)的思想。
算法是程序的靈魂,也是培養(yǎng)學(xué)生計(jì)算思維、邏輯思維的根本。在課程開始階段,使用最簡(jiǎn)單、有趣的工具展示算法設(shè)計(jì),容易引起學(xué)生興趣。筆者在實(shí)踐中首先使用Scratch,其既提供基于網(wǎng)頁的在線版本,也提供離線安裝版本。該系統(tǒng)面向的目標(biāo)首先是中小學(xué)生,設(shè)計(jì)的卡通形象和舞臺(tái)效果很吸引人,對(duì)大學(xué)新生也有足夠的吸引力。
在算法設(shè)計(jì)中,針對(duì)順序、選擇、循環(huán)及混合的處理邏輯,分別選取典型案例,用Scratch 積木可視化呈現(xiàn),能起到良好的演示效果。
在順序結(jié)構(gòu)部分,選用雞兔同籠問題,讓學(xué)生理解從問題到程序的轉(zhuǎn)換過程,“輸入—處理—輸出”的程序流程,以及變量、表達(dá)式等基本概念,如圖1 所示。在選擇結(jié)構(gòu)部分,采用“輸入3 個(gè)數(shù)并輸出最大值”的示例,說明算法的流程結(jié)構(gòu),并以“if”及“if-else”等基本結(jié)構(gòu)塊來實(shí)現(xiàn)算法,如圖2 所示。
圖1 雞兔同籠問題的算法
圖2 求3 個(gè)數(shù)最大值的算法
圖3 從1 累加到100 的算法
圖4 求π 值的算法
為幫助學(xué)生理解數(shù)組這一基本數(shù)據(jù)結(jié)構(gòu),設(shè)計(jì)“輸出Fibonacci 數(shù)列的前20 項(xiàng)”的示例,如圖5(a)所示,在循環(huán)結(jié)構(gòu)中,演示了Fibonacci 數(shù)列的生成過程,同時(shí),舞臺(tái)上的變量和數(shù)列顯示如圖5(b)所示,能夠直觀地看到數(shù)組數(shù)據(jù)的組織及訪問方式。
圖5 生成Fibonacci 數(shù)列的算法
可以看出,采用可視化工具代替流程圖來描述算法,不但簡(jiǎn)單、直觀,而且能夠立刻執(zhí)行、驗(yàn)證,利于學(xué)生理解算法邏輯和數(shù)據(jù)組織方式。
可視化程序的構(gòu)造塊和高級(jí)語言的語句都是對(duì)計(jì)算機(jī)指令執(zhí)行過程的高級(jí)抽象,兩者間具有相似性,只要學(xué)習(xí)了高級(jí)語言的語法規(guī)則和控制結(jié)構(gòu),就能很容易地將可視化程序轉(zhuǎn)化為高級(jí)語言代碼。以圖2 和圖4 為例,轉(zhuǎn)化為C 語言代碼分別如圖6 和圖7 所示。
圖6 輸入3 個(gè)數(shù)求最大值的代碼
圖7 根據(jù)公式求π 值的代碼
這種編程訓(xùn)練在課堂教學(xué)中可以分兩步來實(shí)施,首先由教師主導(dǎo),提出問題并設(shè)計(jì)可視化程序,引導(dǎo)學(xué)生理解算法邏輯;然后由學(xué)生動(dòng)手,根據(jù)語法規(guī)則和程序結(jié)構(gòu),將可視化程序轉(zhuǎn)化為具體的語言代碼,完成從算法邏輯到高級(jí)語言程序的轉(zhuǎn)換。在設(shè)計(jì)可視化程序的過程中,可以引出變量及其存儲(chǔ)方式、運(yùn)算符、表達(dá)式、流程控制和輸入輸出等概念,而這些概念在轉(zhuǎn)化程序時(shí)又可以方便地映射到高級(jí)語言的語法規(guī)則中。通過這一分解,將原來復(fù)雜的編程問題轉(zhuǎn)化為2 個(gè)相對(duì)簡(jiǎn)單的步驟來完成,利于學(xué)生克服畏難情緒,也利于抓住編程的要點(diǎn)。
模塊化編程是程序設(shè)計(jì)課程的核心內(nèi)容之一,高級(jí)語言中一般都通過函數(shù)來實(shí)現(xiàn)模塊化設(shè)計(jì)。Scratch 難以模擬高級(jí)語言中函數(shù)的功能,所以需要一套更加強(qiáng)大的可視化編程工具。筆者采用功能更加強(qiáng)大的可視化編程工具Snap,其提供基于Web 的編程環(huán)境,可視化程序可以保存在客戶端或云端;且支持常用的數(shù)據(jù)類型,完全支持模塊化開發(fā),甚至允許創(chuàng)建新的控制結(jié)構(gòu),能夠完美地用于程序設(shè)計(jì)課程的教學(xué)。
Snap 采用自定義積木的方式制作程序模塊,例如,為求一組數(shù)據(jù)中的最大值,設(shè)計(jì)如圖8 和圖9 所示的程序。其中,第一個(gè)積木塊定義了函數(shù)的原型,函數(shù)名為getArrMax,需要傳遞進(jìn)來一個(gè)數(shù)組s 作為參數(shù),并返回一個(gè)數(shù)據(jù)m 作為最大值;中間部分定義了求最大值的算法,首先假定數(shù)組第一項(xiàng)為最大值,存入變量m,其后循環(huán)遍歷所有的數(shù)組元素,當(dāng)發(fā)現(xiàn)某項(xiàng)值大于m 時(shí),用其替換m 值,這樣循環(huán)結(jié)束時(shí),m 中存放的就是數(shù)組元素的最大值;最后一個(gè)積木塊向主調(diào)程序返回?cái)?shù)據(jù),相當(dāng)于高級(jí)語言中的return 語句。主調(diào)程序如圖9 所示,其核心部分(第三個(gè)積木塊)調(diào)用了自定義的函數(shù)求數(shù)組中的最大值。
圖8 求最大值的自定義模塊
圖9 求數(shù)組最大值的主程序
圖10 求組合數(shù)的自定義模塊
圖11 求階乘的自定義模塊
遞歸是計(jì)算學(xué)科中一種獨(dú)特的思想方法,即:一個(gè)函數(shù)可以直接或間接地調(diào)用自身,前提是必須滿足三個(gè)基本條件:(1)有一套遞推公式;(2)每次遞推后函數(shù)的運(yùn)算規(guī)模都會(huì)減?。唬?)當(dāng)遞推到一定條件時(shí)找到出口。例如,對(duì)求階乘的函數(shù)進(jìn)行改造,設(shè)計(jì)如下的遞推公式,就可以采用遞歸算法來實(shí)現(xiàn)。改造后的求階乘函數(shù)如圖12 所示。
圖12 求階乘的遞歸算法
通過以上示例,可以直觀地展示模塊化設(shè)計(jì)中的核心概念和思想方法。
在該課程的實(shí)踐教學(xué)中發(fā)現(xiàn),很多學(xué)生的編程能力始終跟不上課程節(jié)奏,直到課程結(jié)束,也難以獨(dú)立完成較復(fù)雜的程序。究其原因,一是程序的邏輯較為抽象,學(xué)生沒有理解程序的執(zhí)行過程,難以正確地設(shè)計(jì)程序結(jié)構(gòu);二是高級(jí)語言的語法規(guī)則較為繁瑣,學(xué)生將大量精力都浪費(fèi)在了處理語法錯(cuò)誤上。而當(dāng)這兩個(gè)問題交織在一起的時(shí)候,調(diào)試程序的難度就急劇上升,學(xué)生很難定位錯(cuò)誤到底出在哪里,所以每次實(shí)踐課程的收獲都很有限,很多同學(xué)僅限于將教材上的代碼搬進(jìn)計(jì)算機(jī),使之運(yùn)行起來,而獨(dú)立編寫和調(diào)試代碼的能力明顯不足。
引入可視化編程,將復(fù)雜的問題分解為兩步完成。第一步,根據(jù)實(shí)踐任務(wù)進(jìn)行可視化設(shè)計(jì),深入理解程序邏輯,并且直觀地觀察程序的運(yùn)行過程,相互對(duì)照,熟練掌握程序結(jié)構(gòu);第二步,將可視化程序轉(zhuǎn)化為高級(jí)語言代碼,并上機(jī)調(diào)試。這樣分解的好處在于解耦了程序邏輯錯(cuò)誤與語法錯(cuò)誤之間的關(guān)系,更容易發(fā)現(xiàn)和解決問題。
以選擇排序算法為例,在課堂講解時(shí)幫助學(xué)生理清算法思路,并獨(dú)立完成可視化程序設(shè)計(jì),如圖13 所示,該模塊在數(shù)組元素值互換的代碼塊中加入1 秒延時(shí),運(yùn)行程序時(shí)觀察數(shù)組變量,可以清楚地看到每一輪迭代中元素的互換和移動(dòng),便于理解算法邏輯。當(dāng)可視化程序調(diào)試成功后,可以確保算法邏輯沒有問題,這時(shí)進(jìn)入第二步,轉(zhuǎn)化高級(jí)語言代碼,由于可視化構(gòu)造塊與高級(jí)語言語句塊之間很大程度上有對(duì)應(yīng)關(guān)系,所以這種轉(zhuǎn)化相對(duì)來說難度不大。基于以上步驟,學(xué)生對(duì)程序的理解更加深刻,也更容易編寫和調(diào)試程序。
圖13 選擇排序的可視化算法
筆者將可視化編程引入本科生計(jì)算機(jī)程序設(shè)計(jì)課程的教學(xué),從算法邏輯、代碼轉(zhuǎn)換和模塊化設(shè)計(jì)三個(gè)方面展開研究,在課堂教學(xué)和實(shí)踐教學(xué)中進(jìn)行了嘗試。從教學(xué)效果來看,學(xué)生的學(xué)習(xí)興趣得到了提高,不再畏懼編寫代碼,邏輯思維得到了鍛煉,能夠熟練地描述算法邏輯并進(jìn)行驗(yàn)證,閱讀程序和編寫程序的能力得到了明顯改進(jìn),對(duì)程序的理解上了一個(gè)臺(tái)階。實(shí)踐證明,引入可視化編程,能夠有效改進(jìn)課堂教學(xué)和實(shí)踐教學(xué)的效果。