问答中的新手问题,有比较多的是代码在测试环境下测试通过,但提交作业时却通不过,不知道什么原因。
测试环境下测试通过的理由,是因为作业中指定的输出和自己的输出是“一致”的。这里“一致”加引号,是因为提问者自己的判断,并非作业提交时的判断。
根据实际提供的代码和作业内容,大体问题出在以下几个方面,新手们可以参考一下,如果出现相同情况,可以以此进行检查。
1、只针对测试用例编程
有些新手只看题目中提供的测试数据和测试结果,认为测试数据输入,得到测试结果一致,程序就没毛病了。但题目中的测试数据一般都非常简单,不具有代表性。有的甚至连输入都没有,变量直接写成题目中给的测试数据值,认为这样就可以了。
要知道测试数据只是给你的一个提示,可以作为测试的一个参考,但不是全部,需要仔细阅读题目,考虑各种可能性才能编写出完整的程序。
2、没有按照要求的输入格式接收输入数据
有些题目对输入数据的格式,类型,以及使用的分隔符,可能的提示信息都有明确的要求,那么程序输入就必须完全按要求格式来,因为交作业的检查程序已经按照题目要求给出了测试数据,你是无法修改的。
比如,题目要求输入两个整数,用逗号分隔,那么你就不能是:
scanf(“%d %d”,&a,&b); 这样第二个变量就接收不到正确的输入值了。
还有比如输入明确有提示信息,比如要求输入为 a=10这样子,那么你就必须写成 scanf(“a=%d”,&a);才能成功接收a变量值。
所以一定要审清楚题目要求的输入格式。
3、没有考虑题目中指定的边界值
题目对于输入数据,一般会给出一些范围信息,如数组大小不大于1000,整数范围是0到10的9次方等等。这时候就需要注意两个方面:
一是你定义的接收变量类型是否能够满足取值范围,如果不满足,就容易数据溢出导致结果异常。
二是代码处理过程中其它变量的取值范围,如果不满足,中间结果也会溢出导致异常。
比如求阶乘函数,斐波那契序列,n次方等,值可能会很大,一般的int型满足不了要求。所以必须确认输入数据的取值范围。比如13的阶乘已经超过4字节的范围了,必须long long类型才能满足等等。
4、输出格式与题目要求不一致
输出格式一般题目都有要求,比如什么情况下换行,使用什么分隔符。谁先随后,加什么前缀后缀,变量按什么格式输出,保留几位小数等等。都必须仔细确认,严格按格式输出,只要差一点,结果可能就和作业检查程序的要求不一致而导致结果错误。
5、没有根据题目要求检查输入数据的有效性
部分题目会要求代码检查输入数据的有效性,不符合则要输出一条错误信息,然后程序结束。
6、代码中间处理过程中缺少异常处理
刚开始编程,主要的异常有:
开根号的值不能小于0
除数不能为0
不能操作空指针
数组不能越界访问
当代码中涉及这些方面时,需要先检查有效性,再进行使用。
7、测试用例太少,不能覆盖所有代码块
新手只是根据题目给出的1、2个测试数据进行测试,即认为程序正确。但
其实代码中可能有分支条件,提供的测试用例只满足某部分分支条件,实际有些分支条件的代码未经测试。而作业中的测试用例比较完整,能够覆盖所有分支条件,因此会出现部分正确的情况。此种情况就是某些分支条件有错误,或者上述的边界值未测试导致的。
新手需要逐步学会自己代码的每个分支代码块需要什么样的测试数据能够执行,从而使用这些测试数据进行完整测试。
8、处理效率太低,运行超时
有些题目的功能实现,需要注意算法技巧,否则程序在输入值较小时没有问题,一旦值比较大,就会出现运行时间太长而超时错误。
一旦代码中出现循环次数很大,以及多重循环时就需要注意,一是是否有更好的算法,二是是否在循环过程中有跳出条件,降低循环次数。