林寧
摘要:C語言程序設計題自動評閱技術是實現在線自動評閱的關鍵技術;本文首先分析了C語言編程題傳統的自動評閱技術以及存在的問題,進而提出一種改進的自動評閱技術;最后闡述了實現這種評閱技術所需的注釋去除和標準化printf函數算法,并給出了自動評閱的流程。
關鍵詞:C語言編程題;評閱技術;靜態評閱;動態評閱
中圖分類號:TP31 文獻標識碼:A 文章編號:1007-9416(2018)07-0199-02
1 現狀及問題
C語言程序設計是一門重要的基礎課程。為了提高學生的編程能力,減輕教師的工作量,近幾年諸多專家學者對程序設計語言類課程自動評閱技術展開了研究,取得了一定的成效,但評閱準確率仍有待進一步提高;程序設計題評閱主要從靜態評閱和動態評閱兩個方面進行,即分別從程序的內容和運行結果進行評閱。
靜態評閱一般是檢測源代碼語法是否正確、程序代碼中是否包含題目要求的框架或者是否包含必要的關鍵字等;動態評閱主要是運行程序得出結果,然后跟標準答案進行對比,這種方式對程序的運行輸出有非常嚴格的要求,輸出的字符串必須與標準答案完全匹配,當輸出的字符串多一個或少一個字符將被判為0分。
基于上述評閱方法,筆者認為需考慮以下問題:
(1)靜態評閱應該考慮程序中的注釋內容;如注釋中加入了多種結構的程序片段,這些注釋是不會對程序的編譯產生任何影響,但評閱時包含了題目要求的框架;(2)動態評閱主要是匹配運行結果,因此,在設計題目時往往要給出輸出格式的要求或者例子,但往往因為輸出一個空白符使得與標準答辯不匹配被判為0分。
2 自動評閱技術的改進
基于上述問題,本文提出一種改進判分的方法。適當放寬題目的輸出限制,在評閱上采用靜態評閱與動態評閱相結合的方法;在靜態評閱上,首先去除注釋,避免提交的程序中包含大量注釋,造成誤判;去除注釋及中文符號后再對程序內容進行評閱,主要判斷程序內容是否包含題目要求的關鍵字或程序結構等;
在動態評閱上,由于放寬了對輸出格式的限制,有可能輸出的結果與標準答案不完全匹配,但如果輸出的結果中已經包含了標準答案,這種情況下我們認為程序是正確的。例:題目要求輸出a+b的結果,由于放寬了輸出要求,我們認為輸出語句print(“%d”,a+b)和 printf(“sum=%d\n”,a+b)的輸出都是正確的。基于這種情況,為了確保評閱結果的可靠性,這里采取兩種措施:(1)標準化輸出語句,將多余的字符去除;如將前面例子中的語句printf(“sum=%d\n”,a+b)標準化為print(“%d”,a+b);(2)采用3-5組測試值,多次運行的方法,特別是臨界值測試,多組值正確說明程序是正確的。
3 去除程序中注釋的實現
我們都知道在C語言程序中,有兩種注釋的方法:(1)以“//”開始的單行注釋;(2)以“/*”開始,以“*/”結束的注釋方式。在去除注釋時是不是將“//”與“\n”之間,及 “/*”和“*/”之間的內容簡單去除掉就可以了呢?其實不能簡單的去除,因為C語言輸出語句的特性,簡單去除可能會造成程序的語法錯誤,例如:語句printf(“//Are you OK?”)和printf(“\”//Are you OK?\””)在語法上是沒有錯誤的,如果簡單將“//”后面的部分去除掉,那么將會出現語法上的錯誤。
3.1 去除中文字符的實現
由于中文字符會對去除C語言注釋算法產生影響,因此在去除注釋前先對程序中的中文字符去除。如將content[]數組中的字符去除后保存到content1[]數組中的實現程序片段如下:
for(i=0;i { *(content1+j++)=content[i]; if((content[i]&0x80)&&flag;==1){ j-=2; flag=0; } else if((content[i]&0x80)&&flag;==0)flag=1; else flag=0; } 3.2 去除注釋的算法 在去除程序中的中文字符后,可以采用有窮自動機原理實現對程序中的注釋去除;如圖1,設有窮自動機DFA M=(Q,E,0,,),其中E為ASCII碼集合,轉換狀態集合,A={/,”,*,\n,\},S=E-A。 上述去除注釋算法采用了C語言實現,開始狀態為0態,當到達7狀態時,表示注釋結束。 4 標準化輸出語句 C語言中printf輸出語句形式為printf(格式控制,輸出列表),格式控制中包括格式聲明和普通字符。為了避免普通字符對評閱結果產生影響,需要將這些無關的普通字符去除掉。下面利用有窮自動機原理實現識別printf語句中的格式聲明字符串。 有窮自動機DFA M=(Q,G,0,,),其中G為ASCII碼集合,A={“},B={%},C={\} D={d,i,o,x,X,u,c,s,f,e,E,g,G}為printf函數格式字符集合,E={1~9,l,-,.}為格式附加字符集合,F=G-(A∪B∪C∪D∪E),Q={0,1,2,3}為狀態集合,判斷格式控制字符串如圖2所示,初始狀態為0態,狀態2轉到狀態1時,說明格式控制字符串結束,識別了格式說明就可以實現將格式控制中無關緊要的普通字符去除。 5 評閱的流程 (1)使用Linux系統的“gcc源程序-o可執行文件名”,如果可以生成指定的可執行文件,說明語法上沒有錯誤,轉(2);否則,語法錯誤判為0分,結束評分;(2)去除程序中的注釋,進行靜態評閱,目的是判斷提交的程序是否是題目要求的程序。方法有兩種:①檢測程序中是否包含題目要求的關鍵字,如switch,for,while等;②檢查程序中是否包含題目要求的結構,如:for(;;){}等。如果題目中包含了題目要求的關鍵字或程序結構,那么靜態評閱通過;(3)標準化printf輸出函數,然后通過多組測試值多次運行的方法;如果多組測試的輸出結果中,都包含了標準答案中的關鍵字,那么動態評閱通過;(4)如果靜態評閱和動態評閱都通過,那么程序是正確;否則,程序被判斷錯誤,同時給學生返回錯誤的原因。 6 結語 上述自動評閱技術已經應用到C語言編程題自動評閱系統上,同時系統具備了在線練習與考試的基本功能,并投入教學使用;經過兩年多的運行,系統也得到了逐步的完善。下一步,將繼續完善程序錯誤的提示內容,使錯誤提示更精確。