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