張良
摘 要:本文設(shè)計(jì)了一種針對C語言程序設(shè)計(jì)課程的在線分析與輔導(dǎo)系統(tǒng)。學(xué)生學(xué)習(xí)C語言的過程中,需要通過大量練習(xí)題鞏固所學(xué)知識(shí)。目前,一些教學(xué)平臺(tái)提供了在線判題的功能來檢驗(yàn)程序的對錯(cuò),但存在一些問題。該系統(tǒng)在在線判題系統(tǒng)的基礎(chǔ)上,通過測試用例分析、編譯分析、結(jié)構(gòu)分析等方法,進(jìn)一步細(xì)化檢查和定位學(xué)生程序中的錯(cuò)誤,為學(xué)生提供針對性的輔導(dǎo),對提高學(xué)生的學(xué)習(xí)效率有一定幫助。
關(guān)鍵詞:自主學(xué)習(xí);在線判題智能輔導(dǎo);C語言
中圖分類號(hào):G434 文獻(xiàn)標(biāo)志碼:A 文章編號(hào):1673-8454(2017)07-0086-03
一、引言
C語言程序設(shè)計(jì)是一門實(shí)踐性很強(qiáng)的課程,在教學(xué)過程和學(xué)生的自主學(xué)習(xí)過程中,都需要通過大量的練習(xí)題來鞏固所學(xué)知識(shí)、檢驗(yàn)學(xué)習(xí)效果。很多C語言課程教學(xué)平臺(tái)和自主學(xué)習(xí)平臺(tái)也提供了大量的題目(主要是編程題)供學(xué)生練習(xí)。由于學(xué)生數(shù)量眾多,學(xué)習(xí)時(shí)間也不一致,教師很難及時(shí)為每位學(xué)生所做的題目進(jìn)行評價(jià)并給出針對性的指導(dǎo)。
目前一些教學(xué)實(shí)踐過程中采用在線判題(Online Judge)系統(tǒng)進(jìn)行自動(dòng)評分。[1][2]在線判題系統(tǒng)大多采用測試用例的方法進(jìn)行判斷,即編制若干組測試用例,模擬運(yùn)行程序,將數(shù)據(jù)輸入程序,并將輸出結(jié)果與預(yù)期結(jié)果進(jìn)行匹配,如果完全匹配成功判對,否則判錯(cuò)。這種方法能夠很直觀地判斷學(xué)生程序的對錯(cuò),對促進(jìn)學(xué)生提高實(shí)驗(yàn)水平也有很大幫助,但這種判斷方法并不能完全適用于學(xué)生自主學(xué)習(xí)的場景。
(1)在線判題的前提是必須保證程序能夠運(yùn)行。而學(xué)生(尤其是初學(xué)者)編寫的源程序可能存在個(gè)別語法錯(cuò)誤而不能通過編譯并生成可執(zhí)行文件。這些程序不能得到分析評價(jià)和針對性輔導(dǎo)。
(2)輸出結(jié)果與預(yù)期成果進(jìn)行文本匹配來判斷對錯(cuò)的方式,使一些只在輸出格式上有錯(cuò)誤的程序判斷為錯(cuò)。程序中某些數(shù)據(jù)類型的精度問題也可能導(dǎo)致輸出結(jié)果有誤差,從而導(dǎo)致判斷為錯(cuò)。
(3)目前的在線判題系統(tǒng)只能對題目整體進(jìn)行判斷對錯(cuò),不能具體定位到程序出問題的部分并針對學(xué)生的錯(cuò)誤進(jìn)行輔導(dǎo)。
自主學(xué)習(xí)過程中,很多初學(xué)者可能找不到以上出錯(cuò)的原因,而浪費(fèi)了很多學(xué)習(xí)時(shí)間,降低了學(xué)習(xí)效率。而在教師現(xiàn)場輔導(dǎo)時(shí),可以很容易發(fā)現(xiàn)其中的錯(cuò)誤,并可以根據(jù)其程序給出分析評價(jià)并進(jìn)行指導(dǎo)。近年來,許多教改項(xiàng)目對在線判題系統(tǒng)進(jìn)行改進(jìn),主要的研究思路有通過優(yōu)化判題流程[3]、語義檢測的穩(wěn)定模型[4]、基于關(guān)鍵字和序列匹配[5]等方法,這些方法在一定程度上解決了以上問題。本文借鑒以上思路,結(jié)合測試用例、編譯系統(tǒng)、結(jié)構(gòu)分析法等設(shè)計(jì)了一種在線分析及輔導(dǎo)系統(tǒng),可以用于應(yīng)用C語言教學(xué)平臺(tái)及自主學(xué)習(xí)系統(tǒng),經(jīng)過測試,在線分析和輔導(dǎo)系統(tǒng)可以模擬教師現(xiàn)場指導(dǎo),從而提高學(xué)生學(xué)習(xí)的效率。
二、系統(tǒng)設(shè)計(jì)
基于對在線判題系統(tǒng)優(yōu)缺點(diǎn)的分析,本系統(tǒng)采用以下原則進(jìn)行設(shè)計(jì):①系統(tǒng)基于成熟的在線判題系統(tǒng),采用測試用例法對學(xué)生提交的源程序進(jìn)行初步分類。②對于初步分類為錯(cuò)誤的程序再采用編譯分析、結(jié)構(gòu)分析等方法進(jìn)行進(jìn)一步分析。設(shè)系統(tǒng)整體流程如圖1 所示。
整個(gè)系統(tǒng)分為四個(gè)部分——測試分析模塊、編譯分析模塊、結(jié)構(gòu)分析模塊、輔導(dǎo)模塊。
首先對源程序進(jìn)行編譯鏈接,如果編譯成功,可以生成exe文件,調(diào)用測試模塊進(jìn)行測試。如果編譯不成功,則需要對源文件進(jìn)行進(jìn)一步分析。①調(diào)用編譯分析模塊解析程序中出現(xiàn)的語法錯(cuò)誤并進(jìn)行自動(dòng)修正。②調(diào)用結(jié)構(gòu)分析模塊分析程序的結(jié)構(gòu)問題。
在測試模塊中,如果測試用例全部通過測試,程序判對并將此程序加入?yún)⒖即鸢笌熘?;如果部分通過,則進(jìn)行用例分析,并調(diào)用結(jié)構(gòu)分析模塊分析程序,如果全部未通過,直接調(diào)用結(jié)構(gòu)分析模塊進(jìn)行分析。針對各個(gè)模塊分析、對比得到的程序問題,分類別(語法錯(cuò)誤、格式錯(cuò)誤、結(jié)構(gòu)錯(cuò)誤等)對學(xué)生進(jìn)行針對性輔導(dǎo)。
三、詳細(xì)設(shè)計(jì)
1.測試分析模塊
測試模塊首先要設(shè)置若干組合理的測試用例。測試用例需要覆蓋到程序的所有結(jié)構(gòu)路徑。如分支結(jié)構(gòu)中,每個(gè)分支至少要有1組測試用例。測試用例除了設(shè)置輸入輸出外,還需要設(shè)置測試用例說明,如分支結(jié)構(gòu)中,每組測試用例必須設(shè)置該分支測試用例說明。
通過測試用例對程序進(jìn)行模擬運(yùn)行,如果測試用例全部通過,程序得滿分,如果該程序的結(jié)構(gòu)模塊與參考答案庫所有答案均不同,將該程序加入到參考答案庫。如果部分通過,對未通過測試的用例進(jìn)行分析,得到程序出現(xiàn)錯(cuò)誤結(jié)構(gòu)路徑。針對部分同學(xué)的格式、數(shù)據(jù)類型精度等情況可能造成判錯(cuò)的問題,需要在現(xiàn)有的測試用例方法基礎(chǔ)上增加容錯(cuò)的機(jī)制。常見的格式錯(cuò)誤有:
多寫或少寫空格、制表符、回車符等符號(hào)造成的錯(cuò)誤。格式控制串“%m.nf”“%md”未按要求書寫造成的輸出格式錯(cuò)誤。
將間隔符號(hào)如“,”“;”等寫錯(cuò)引起的錯(cuò)誤。
在輸出時(shí)多寫或漏寫了其他說明性文字引起的錯(cuò)誤,比如輸出變量a的值。格式輸出要求“a=5”,而學(xué)生程序只輸出了 5,漏寫“a=”,或者要求輸出5,而程序輸出“a=5”。
為解決以上由于格式問題導(dǎo)致系統(tǒng)判錯(cuò),需要對測試用例的參考輸出結(jié)果和用戶程序的實(shí)際輸出結(jié)果進(jìn)行歸一化操作后再次進(jìn)行比對,并對測試用例中的輸出結(jié)果進(jìn)行細(xì)化設(shè)置。
(1)格式歸一化操作。對測試用例的參考輸出結(jié)果或程序的實(shí)際輸出中常用的控制字符如空格、制表符、換行符等為統(tǒng)一的間隔標(biāo)記。歸一化后再次進(jìn)行比對。
(2)精度歸一化。在編寫程序過程中,由于學(xué)生用的數(shù)據(jù)類型不合適可能導(dǎo)致數(shù)據(jù)結(jié)果存在誤差,如float類型數(shù)據(jù)在6位數(shù)之后出現(xiàn)的精度誤差,需要對學(xué)生提供的源程序數(shù)據(jù)精度進(jìn)行歸一化,統(tǒng)一為精度較高的數(shù)據(jù)類型。
(3)輸出結(jié)果的細(xì)化設(shè)置。在《C語言程序設(shè)計(jì)》課程中,編程題輸出結(jié)果一般可分為“說明性字符串”、“計(jì)算型數(shù)值”、“間隔符號(hào)”等三大類,其中核心為“計(jì)算型數(shù)值”。在設(shè)置測試用例參考答案時(shí)分別細(xì)化標(biāo)記三類輸出,在進(jìn)行結(jié)果比對時(shí)按照“完全匹配—>計(jì)算性數(shù)值匹配—>間隔符號(hào)匹配—>說明性字符串匹配”的順序進(jìn)行比對結(jié)果。
2.編譯分析模塊
目前的在線判題系統(tǒng),一般是在服務(wù)端使用編譯工具對用戶提交的源程序進(jìn)行編譯鏈接,如果能夠編譯通過,進(jìn)入測試用例模塊進(jìn)行測試。如果不能通過,則進(jìn)行報(bào)錯(cuò)。編譯系統(tǒng)所報(bào)的錯(cuò)誤基本都是針對源程序中存在的語法錯(cuò)誤,有的指示位置有偏差,有的錯(cuò)誤是由前面的錯(cuò)誤引起的,有的描述不直觀,對初學(xué)者查找錯(cuò)誤造成很大的誤解,不能直接對學(xué)生修改程序起到指導(dǎo)作用。本系統(tǒng)根據(jù)教師在教學(xué)實(shí)踐中的經(jīng)驗(yàn),將編譯系統(tǒng)的報(bào)錯(cuò)進(jìn)行分析,反推出源程序中的書寫錯(cuò)誤,并進(jìn)行直觀提示。由于每一種編譯器的報(bào)錯(cuò)提示有差異,本文以VC6.0 編譯器為例,如表1所示。
根據(jù)編譯器的提示錯(cuò)誤的順序依次自動(dòng)修正源程序中的錯(cuò)誤后重新進(jìn)行編譯,如果編譯成功,則重新進(jìn)入測試用例模塊進(jìn)行測試,如果編譯不成功,再次修正錯(cuò)誤,進(jìn)行編譯,直至可以編譯或者修正次數(shù)大于設(shè)定的閾值。
3.結(jié)構(gòu)分析模塊
為了分析源程序的結(jié)構(gòu),需要為每道題目設(shè)置參考答案。參考答案的要求一是要標(biāo)準(zhǔn)化,采用標(biāo)準(zhǔn)流程和通用方法解決問題,參考答案書寫要求規(guī)范,并詳細(xì)注釋。二是要鼓勵(lì)多樣化思維,答案不一定唯一,應(yīng)給出一種或幾種參考答案,形成答案庫。在判題的過程中,對全部通過測試的新答案,也要加入到參考答案庫中。
C語言程序的結(jié)構(gòu)有如下特點(diǎn):
絕大多數(shù)C語言中源程序都可以轉(zhuǎn)化為“預(yù)處理命令+若干個(gè)函數(shù)”的結(jié)構(gòu),細(xì)分到每個(gè)函數(shù),又可以分為順序、選擇和循環(huán)3 種控制結(jié)構(gòu)及其嵌套結(jié)構(gòu)。[5]
關(guān)鍵語句。C語言有32個(gè)關(guān)鍵詞,每個(gè)關(guān)鍵詞往往代表一種語法結(jié)構(gòu)。根據(jù)關(guān)鍵詞,可得到關(guān)鍵語句序列。
即使算法相同,不同人編寫的程序也可能完全不同,可能變量名不同、變量定義的順序不同、控制結(jié)構(gòu)不同(比如循環(huán)語句,有人習(xí)慣用for語句,有人習(xí)慣用while語句)等。
根據(jù)C語言程序的結(jié)構(gòu)特點(diǎn),將整個(gè)程序解析為若干個(gè)模塊,解析順序:①預(yù)處理命令部分。②全局定義部分。定義全局變量、全局函數(shù)聲明等信息。③函數(shù)模塊:根據(jù)函數(shù)模塊的結(jié)構(gòu)特點(diǎn),經(jīng)過文本分析,可以獲得函數(shù)的結(jié)構(gòu),并獲取函數(shù)名、返回值類型、參數(shù)列表等信息。④關(guān)鍵語句序列,根據(jù)C 語言中的關(guān)鍵字,獲取函數(shù)中控制結(jié)構(gòu)語句。形成關(guān)鍵語句序列。
通過解析程序可以得到程序結(jié)構(gòu)分析結(jié)果及層次結(jié)構(gòu)。如:
函數(shù)結(jié)構(gòu)(參數(shù)列表)
輸入語句
循環(huán)結(jié)構(gòu)
分支結(jié)構(gòu)
循環(huán)結(jié)構(gòu)
輸出語句
系統(tǒng)采用XML格式進(jìn)行存儲(chǔ),并進(jìn)行比對。
4.輔導(dǎo)模塊
在自主學(xué)習(xí)過程中,學(xué)生進(jìn)行測試的目的主要是發(fā)現(xiàn)學(xué)習(xí)的薄弱環(huán)節(jié),并得到針對性的指導(dǎo)。根據(jù)測試分析模塊、編譯分析模塊、結(jié)構(gòu)分析模塊得到的分析結(jié)果,針對學(xué)生程序中出現(xiàn)的主要問題,對學(xué)生進(jìn)行針對性指導(dǎo)。
如果程序判定為正確,將成績記錄為滿分,系統(tǒng)推薦下一個(gè)難度的學(xué)習(xí)資料和題目進(jìn)行練習(xí)。如果未得滿分,依次根據(jù)以上三個(gè)模塊得到的分析結(jié)果進(jìn)行針對性指導(dǎo)。如果為格式問題,給學(xué)生展示正確的書寫格式,并為學(xué)生提供格式方面的強(qiáng)化指導(dǎo),為其推薦格式方面的訓(xùn)練題目,加強(qiáng)訓(xùn)練。如果是語法錯(cuò)誤,根據(jù)編譯分析系統(tǒng)分析結(jié)果,給出錯(cuò)誤提示,指出修正方法。未按題目要求編寫函數(shù),或者函數(shù)的格式不正確,強(qiáng)化其函數(shù)定義方法及書寫格式、函數(shù)參數(shù)設(shè)置等,并提供參考范例供學(xué)生學(xué)習(xí)。結(jié)構(gòu)型錯(cuò)誤,為學(xué)生提示標(biāo)準(zhǔn)答案的結(jié)構(gòu)框架及參考范例。
四、總結(jié)
本文設(shè)計(jì)了一種C語言程序智能評價(jià)及輔導(dǎo)系統(tǒng),目前在《C語言程序設(shè)計(jì)》課程的自主學(xué)習(xí)平臺(tái)中進(jìn)行了應(yīng)用測試,作為課程的輔助教學(xué)平臺(tái)。經(jīng)測試與綜合分析,取得了較好的效果。
(1)本系統(tǒng)細(xì)化了在線判題系統(tǒng)判題規(guī)則,改變以往的練習(xí)系統(tǒng)只判斷對錯(cuò)的模式,通過編譯分析模塊和結(jié)構(gòu)分析模塊,能更細(xì)致找出學(xué)生的錯(cuò)誤和給出細(xì)化的建議,提高了學(xué)生學(xué)習(xí)的效率。
(2)在判題系統(tǒng)的基礎(chǔ)上增加了針對性輔導(dǎo)的功能,學(xué)生通過自主學(xué)習(xí)系統(tǒng),不僅可以檢驗(yàn)自己的學(xué)習(xí)水平,還可以得到針對性的輔導(dǎo),發(fā)現(xiàn)學(xué)習(xí)的薄弱環(huán)節(jié),提高學(xué)生的學(xué)習(xí)水平。
(3)在實(shí)際運(yùn)行中,也發(fā)現(xiàn)了系統(tǒng)的一些缺點(diǎn),比如對個(gè)別解題思路比較特別的程序不能給出準(zhǔn)確的解讀,智能化還有待提高,在下一步工作中還要繼續(xù)進(jìn)行研究。
參考文獻(xiàn):
[1]熊茜,雷亮,許莎,陳劉奎.基于在線判題系統(tǒng)的C語言實(shí)驗(yàn)教學(xué)改革[J].重慶科技學(xué)院學(xué)報(bào)(社會(huì)科學(xué)版),2015(10):67-69.
[2]廖雪花,厲蘭潔,唐思娩.基于Online Judge 的C語言程序設(shè)計(jì)實(shí)驗(yàn)課教學(xué)改革研究[J].計(jì)算機(jī)教育,2016(6):130-132.
[3]蔣燕敏.自動(dòng)判題算法及網(wǎng)絡(luò)考試平臺(tái)研究[D].浙江:浙江工業(yè)大學(xué),2014.
[4]陳晶晶,陳華,范宜標(biāo).C語言智能評分系統(tǒng)的開發(fā)[J].龍巖學(xué)院學(xué)報(bào),2016(2):75-80.
[5]楊利軍,董紅斌,梁意文,譚成予.源程序語義檢測的穩(wěn)定模型分析方法[J].計(jì)算機(jī)工程,2006(15):96-98.
[6]王力洪.基于關(guān)鍵字和序列匹配的自動(dòng)評分算法的研究[J].福建電腦,2015(12):10-12.
[7]喬少杰,楊燕,葛永明,張翠芳,戴齊.基于B/S架構(gòu)的多用戶在線程序評判系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)工程與科學(xué),2011(s1):58-61.
(編輯:王天鵬)