李建華,許芝卉*
(山西大同大學數學與統計學院,山西大同 037200)
C 語言是高級程序設計語言,是各高校中理工科的一門必修課,也是計算機等級考試的科目之一。C語言的編程題如果能夠用計算機自動評分的話,那么對學生編程練習自評以及利用計算機實現無紙化考試都具有十分重要的意義。因此,各種自動評分系統也應用而生。動態測試評分法是目前較多在線測試系統中用到的評分方法,其前提是程序能運行成功,程序編譯失敗或運行結果不匹配等情況都以0分處理[1-3]。這種評分方法對學生的學習考察存在著片面性。我們知道C 語言畢竟是語言類,用它編程和我們用漢語言寫作一樣,存在著多樣性。這樣由于學生編寫的源代碼存在著多樣性,以及現有的技術對程序的理解度、語義分析的準確度還不是很成熟等原因,評分的細節及準確性會受到影響。
那么,如果為了迎合評分軟件的功能,對于程序設計題規定算法結構,這樣就背離了此類試題考核的初衷,也不符合程序設計的靈活多樣性特征。語言類課程教學的最終目的就是培養學生的實際應用能力,然而面對紛繁復雜的現實問題,不同學生對于同一個問題的解答結果也是不盡相同的。因此,沒有必要也不應該強求答案的一致性,這就給計算機自動評分帶來很大困難。
目前針對程序主觀題的自動評分方法主要分為兩類:靜態分析和動態測試。這兩種方法各有利弊。動態測試實現起來簡單快速,但局限性強,只能處理程序完整的題目,結果只是滿分或零分兩種情況,不能按步驟給分;靜態分析與人工閱卷評分方式較為貼近,可以按照程序步驟給分,這樣也就可以適用于絕大多數程序題的自動閱卷。然而靜態分析通常需要完備答案庫,才可能使學生的多樣化答案找到匹配答案。所以這會出現本來答案正確但是沒匹配到答案的情況,導致不能完全保證評分正確。針對這些問題,提出一種基于人工評分思想的評分算法,從實際出發,采用靜態分析、動態測試相結合的方法進行自動評分,盡可能減少錯誤批改,客觀公正地給出考試成績。
教師在人工評分時會將學生編寫的程序與試卷標準答案進行比對,如果與標準答案的結果一樣就會給出滿分。如果學生編寫的代碼與所有的備案答案都不完全一樣,教師會根據評分標準按知識點給分。正是參考人工閱卷的這種方式來解決自動閱卷的難點問題。
先用動態測試評分方法來測試。動態測試的過程是將源程序進行預處理和編譯,然后檢測是否生成相應的可執行文件[4-5]。動態測試記錄程序運行時的編譯結果與運行結果,如果編譯成功,并且結果運行正確,那就是滿分;如果編譯成功,但結果運行與答案不匹配,或編譯不成功,那么轉為靜態評分法。靜態分析方法的本質是模式匹配,也就是對考生答案的源程序進行語法語義等分析,依據考生答案和標準答案之間的匹配度給考生判分。
目前的很多自動化評分系統的評分策略是按結果評分的,這種策略會產生不合理的結果,如:僅因為個別小錯誤而使一個基本正確的程序不能編譯運行,這種情況系統會給予整個程序不得分的結果。就這一不合理情況進行一些改進,系統設計的總體思路如圖1所示。

圖1 系統流程圖
建立測試程序相應的輸入、輸出對的集合,對學生答題的源程序進行編譯連接,編譯成功,運行學生程序,然后判定對于特定的輸入程序能否得到期待的輸出。如果運行結果與標準答案內容完全相同,則說明結果正確,得滿分。用windows 內部功能,記錄考生操作的每一步驟,形成獨立日志文件,傳送到服務器上,作為評分的必需內容。評分時,如搜索不到指定日志文件,就可認定為“抄襲”[6]。根據C程序的編譯原理,源文件編譯成功后會生成相對應的后輟為.obj 文件和后輟為.exe 的目標文件,可通過判斷編譯之后是否有后輟為.exe文件來確定編譯是否成功。
當程序編譯不成功,或運行結果與答案不符,轉入靜態分析評分。以下是總結的幾種靜態分析方式。
2.2.1 基于得分語句查找的評分
人工評分時,教師會在學生所寫程序中找出相應能得分的點,并根據評分標準給出相應的得分,如果沒有找到關鍵得分的程序段,就不會得到分數。由教師提供一系列試題答案,記錄在答案文本文件中。教師在答案模板中把關鍵得分語句按得分點分成一段一段的,并標配相應得分分數。自動評分過程是對學生源程序進行詞法分析后,查找能與關鍵得分語句相匹配的程序語句,并把相應可得的分數累計起來。該方法保證在學生程序有語法錯誤、不能正常運行的情況下,也能得到合理的分數。
2.2.2 算法思想的對比評分
算法思想對比,可以通過抽取程序骨架與標準骨架相比對。這種方法可用于語義有錯誤的情況。如那些編譯成功,但運行出來的結果卻與答案不同,或者是無法編譯運行的代碼,可以通過提取骨架的方法來檢查其算法思想是否合理準確。雖然在C語言中針對于同一個問題的解答結果是不盡相同的,可以編寫出多種不同的代碼,但是其算法思想是基本一致的[6]。例如用不同的方法來實現排序:
(1)用起泡法來實現排序

(2)用選擇排序法實現排序

(3)用一般排序法實現排序


根據C語言的關鍵字對以上幾種程序進行骨架的抽取,盡管用不同的方法來實現程序,但我們會發現骨架都為for()for()if(){}或者for(){for()if(){}}等,這樣就可以用從考生文抽取的骨架與標準的骨架相對比,根據異同程度給予一定的分數。
2.2.3 書寫格式多樣化評分
C 語言程序的一大特點就書寫格式靈活多樣。如命名多樣性,同樣性質的變量可以定義為不同的名稱,標識符只要滿足規范可以任意組合字符,而且書寫時會出現有無空格之類的區別。針對這種情形可以先采用正則表達式來表示程序中的關鍵算法,然后再進行字符匹配方法。例如一段簡單的程序

可表示為:


這種形式可以表示程序的核心算法,而且具有通用性。
2.2.4 基于程序語義分析的評分
對程序進行語義分析,將學生程序進行程序標準化轉換,這種轉化就是消除程序表達方式多樣化,如把while 和do…while 語句等表循環的語句都換成for 語句。然后與由教師提供的記錄在答案文本文件中的一系列模板程序(相當于提供編程題的參考答案)進行程序匹配。計算它們的語義相似程度,給出學生程序的評分結果。語義相似度越高,程序得分就越高。該方法保證在程序運行結果有誤但基本思路正確的情況下也可以得到合理的分數[7]。
根據人工批卷的主觀思想而設計的自動評分系統算法,自動評分系統可用于面向學生實踐能力考核的C語言編程題考試。動態測試與靜態分析相結合可以更好得體現人工閱卷的思維過程,如果將上述的四種靜態分析方法能靈活地結合在一起的話,效果會更佳。自動評分系統不僅可以減輕教師的閱卷負擔,還可以用于學生自評,其反饋結果可幫助學生進一步了解學情,從而有針對的進行改進與學習,對于實現無紙考試具有重要的實際應用意義和推廣價值。