一种改进的C语言程序设计题自动评阅技术

2018-10-10 11:11林宁
数字技术与应用 2018年7期

林宁

摘要: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语言编程题自动评阅系统上,同时系统具备了在线练习与考试的基本功能,并投入教学使用;经过两年多的运行,系统也得到了逐步的完善。下一步,将继续完善程序错误的提示内容,使错误提示更精确。